web-dev-qa-db-ja.com

Cで整数の長さを見つける

Cで整数の長さを見つける方法を知りたいです。

例えば:

  • 1 => 1
  • 25 => 2
  • 12512 => 5
  • 0 => 1

等々。

Cでこれを行うにはどうすればよいですか?

55
marabunta2048

C:

なぜ数値の絶対値の10を底とするログを取得し、それを切り捨てて、1を追加しないのですか?これは、0以外の正数と負数に対して機能し、文字列変換関数を使用する必要がなくなります。

log10abs、およびfloor関数は、math.hによって提供されます。例えば:

int nDigits = floor(log10(abs(the_integer))) + 1;

log10(0)the_integer != 0に従って-HUGE_VALを返すため、これをman 3 logに確実に句でラップする必要があります。

さらに、負の符号を含む数値の長さに関心がある場合、入力が負の場合、最終結果に1を追加することができます。

Java:

int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;

N.B。このメソッドに含まれる計算の浮動小数点の性質により、より直接的なアプローチよりも遅くなる場合があります。効率に関する議論については、Kangkanの回答に対するコメントを参照してください。

94
Jordan Lewis

fastおよびvery simpleのソリューションに興味がある場合、次の方法が最も速いかもしれません(これは問題の数値の確率分布に依存します)。

int lenHelper(unsigned x) {
    if (x >= 1000000000) return 10;
    if (x >= 100000000)  return 9;
    if (x >= 10000000)   return 8;
    if (x >= 1000000)    return 7;
    if (x >= 100000)     return 6;
    if (x >= 10000)      return 5;
    if (x >= 1000)       return 4;
    if (x >= 100)        return 3;
    if (x >= 10)         return 2;
    return 1;
}

int printLen(int x) {
    return x < 0 ? lenHelper(-x) + 1 : lenHelper(x);
}

最も独創的なソリューションで賞を獲得することはできないかもしれませんが、理解するのは簡単であり、実行するのも簡単です。そのため、高速です。

MSCを使用してQ6600で、次のループでこれをベンチマークしました。

int res = 0;
for(int i = -2000000000; i < 2000000000; i += 200) res += printLen(i);

このソリューションの所要時間は0.062秒で、スマート対数アプローチを使用したピートカーカムによる2番目に速いソリューションの所要時間は0.115秒で、ほぼ2倍の時間がかかります。ただし、10000以下の数値の場合、スマートログは高速です。

ある程度の明確さを犠牲にして、スマートログをより確実に破ることができます(少なくともQ6600では)。

int lenHelper(unsigned x) { 
    // this is either a fun exercise in optimization 
    // or it's extremely premature optimization.
    if(x >= 100000) {
        if(x >= 10000000) {
            if(x >= 1000000000) return 10;
            if(x >= 100000000) return 9;
            return 8;
        }
        if(x >= 1000000) return 7;
        return 6;
    } else {
        if(x >= 1000) {
            if(x >= 10000) return 5;
            return 4;
        } else {
            if(x >= 100) return 3;
            if(x >= 10) return 2;
            return 1;
        }
    }
}

このソリューションは、大きな数値では依然として0.062秒であり、小さな数値では約0.09秒に低下します。どちらの場合も、スマートログアプローチよりも高速です。 (gccはコードを高速化します;このソリューションでは0.052秒、スマートログアプローチでは0.09秒です)。

44
Eamon Nerbonne
int get_int_len (int value){
  int l=1;
  while(value>9){ l++; value/=10; }
  return l;
}

2番目は負の数でも機能します:

int get_int_len_with_negative_too (int value){
  int l=!value;
  while(value){ l++; value/=10; }
  return l;
}
24
zed_0xff

次のような関数を作成できます。

unsigned numDigits(const unsigned n) {
    if (n < 10) return 1;
    return 1 + numDigits(n / 10);
}
18
Kangkan

nの長さ:

length =  ( i==0 ) ? 1 : (int)log10(n)+1;
10
Fritz G. Mehner

整数の桁数x1 + log10(x)と等しくなります。だからあなたはこれを行うことができます:

#include <math.h>
#include <stdio.h>

int main()
{
    int x;
    scanf("%d", &x);
    printf("x has %d digits\n", 1 + (int)log10(x));
}

または、ループを実行して自分で桁を数えることができます。数値が0になるまで10で整数除算を行います。

int numDigits = 0;
do
{
    ++numDigits;
    x = x / 10;
} while ( x );

最初のソリューションで整数が1の場合は0を返すように少し注意する必要があり、負の整数も処理する必要があります(-xの場合はx < 0を使用します) )。

7
IVlad

最も効率的な方法は、整数の最高ビットセットを決定するために使用されるものと同様の、高速対数ベースのアプローチを使用することです。

size_t printed_length ( int32_t x )
{
    size_t count = x < 0 ? 2 : 1;

    if ( x < 0 ) x = -x;

    if ( x >= 100000000 ) {
        count += 8;
        x /= 100000000;
    }

    if ( x >= 10000 ) {
        count += 4;
        x /= 10000;
    }

    if ( x >= 100 ) {
        count += 2;
        x /= 100;
    }

    if ( x >= 10 )
        ++count;

    return count;
}

この(おそらく時期尚早な)最適化には、ネットブックでの2000万回の呼び出しに対して0.65秒かかります。 zed_0xffのような反復除算には1.6秒かかり、Kangkanのような再帰的除算には1.8秒かかり、浮動小数点関数(Jordan Lewisのコード)の使用には6.6秒かかります。 snprintfの使用には11.5秒かかりますが、整数だけでなく、snprintfが任意の形式に必要なサイズを提供します。ジョーダンは、タイミングの順序が自分のプロセッサで維持されておらず、私のプロセッサよりも浮動小数点が高速であると報告しています。

最も簡単な方法は、snprintfに印刷された長さを尋ねることです。

#include <stdio.h>

size_t printed_length ( int x )
{
    return snprintf ( NULL, 0, "%d", x );
}

int main ()
{
    int x[] = { 1, 25, 12512, 0, -15 };

    for ( int i = 0; i < sizeof ( x ) / sizeof ( x[0] ); ++i )
        printf ( "%d -> %d\n", x[i], printed_length ( x[i] ) );

    return 0;
}
7
Pete Kirkham

はい、sprintfを使用します。

int num;
scanf("%d",&num);
char testing[100];
sprintf(testing,"%d",num);
int length = strlen(testing);

または、log10関数を使用して数学的にこれを行うことができます。

int num;
scanf("%d",&num);
int length;
if (num == 0) {
  length = 1;
} else {    
  length = log10(fabs(num)) + 1;
  if (num < 0) length++;
}
7
Jamie Wong

正しいsnprintf実装:

int count = snprintf(NULL, 0, "%i", x);
6
sam hocevar
int digits=1;

while (x>=10){
    x/=10;
    digits++;
}
return digits;
4
Pasi
sprintf(s, "%d", n);
length_of_int = strlen(s);
2
OK_or_CANCEL

これを使用できます-

(data_type)log10(variable_name)+1

例:

len =(int)log10(number)+1;

2
user7122338

とても簡単

int main() {
    int num = 123;
    char buf[50];

    // convert 123 to string [buf]
    itoa(num, buf, 10);

    // print our string
    printf("%s\n", strlen (buf));

    return 0;
}
1
Mauro

ゼロになるまで10で除算を続け、分割数を出力します。

int intLen(int x)
{
  if(!x) return 1;
  int i;
  for(i=0; x!=0; ++i)
  {
    x /= 10;
  }
  return i;
}
0
Graphics Noob

私のやり方:

数値が10で割り切れない限り分割します。

u8 NumberOfDigits(u32 number)
{
    u8 i = 1;
    while (number /= 10) i++;

    return i;
}

他の命題と比べてどれくらい速いのかわかりません。

0
tBlabs

これはネガティブとポジティブの両方のインタイガーに当てはまります

    int get_len(int n)
    {
        if(n == 0)
        return 1;

        if(n < 0)    
        {
           n = n * (-1); // if negative
        }

        return  log10(n) + 1;
    }

同じロジックがforループになります

  int get_len(int n)
  {
       if(n == 0)
       return 1;

       int len = 0;
       if(n < 0)
       n = n * (-1);

       while(n > 1)
       {
          n /= 10;
          len++;
       }

       return len;
  }
0
Djolo
int returnIntLength(int value){
    int counter = 0;
    if(value < 0)
    {
        counter++;
        value = -value;
    }
    else if(value == 0)
        return 1;

    while(value > 0){
        value /= 10;
        counter++;
    }

    return counter;
}

この方法は、このタスクに適していると思います。

値と回答:

  • -50-> 3 //カウントします-マイナスをカウントしたくない場合も1文字としてカウントし、5行目からcounter ++を削除します。

  • 566666-> 6

  • 0-> 1

  • 505-> 3

0
Sa'gear Giree

より詳細な方法は、この関数を使用することです。

int length(int n)
{
    bool stop;
    int nDigits = 0;
    int dividend = 1;
    do
    {
        stop = false;
        if (n > dividend)
        {
            nDigits = nDigits + 1;
            dividend = dividend * 10;
        }
        else {
            stop = true;
        }


    }
    while (stop == false);
    return nDigits;
}
0
Chirag M
int intlen(int integer){
    int a;
    for(a = 1; integer /= 10; a++);
    return a;
}
0
Ruza

親切に私の答えを見つけてください、それは1行のコードです:

#include <stdio.h> int main(void){ int c = 12388884; printf("length of integer is: %d",printf("%d",c)); return 0; }

それはシンプルでスマートです!気に入ったら投票してください!

0
Nasir Shah

私の意見では、最短かつ最も簡単な解決策は次のとおりです。

int length , n;

printf("Enter a number: ");

scanf("%d", &n);

length = 0;

while (n > 0) {
   n = n / 10;
   length++;
}

printf("Length of the number: %d", length);
0
Flo