Подтвердить что ты не робот

Поиск длины целого числа в C

Я хотел бы знать, как я могу найти длину целого числа в C.

Например:

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

и т.д.

Как я могу сделать это в C?

4b9b3361

Ответ 1

C:

Почему бы просто не взять базовый лог абсолютного значения числа, округлить его и добавить? Это работает для положительных и отрицательных чисел, которые не равны 0, и избегает использования любых функций преобразования строк.

Функции log10, abs и floor предоставляются math.h. Например:

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

Вы должны обернуть это в предложение, гарантирующее, что the_integer != 0, так как log10(0) возвращает -HUGE_VAL в соответствии с man 3 log.

Кроме того, вы можете добавить его к окончательному результату, если вход отрицательный, если вас интересует длина номера, включая его отрицательный знак.

Java:

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

N.B.. С плавающей точкой вычислений, связанных с этим методом, может быть медленнее, чем более прямой подход. См. Комментарии для ответа Kangkan для обсуждения эффективности.

Ответ 2

Если вы заинтересованы в быстром и очень простом решении, следующее может быть самым быстрым (это зависит от распределения вероятностей соответствующих чисел):

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);
}

В то время как он может не выиграть призы для самого гениального решения, это тривиально, чтобы понять, а также тривиально выполнить - так быстро.

В Q6600 с использованием MSC я сравнивал это со следующим циклом:

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

Это решение занимает 0.062 с, второе - самое быстрое решение Пита Киркхема с использованием метода "умный логарифм" занимает 0.115 с - почти в два раза больше. Однако для чисел около 10000 и ниже интеллектуальный журнал работает быстрее.

За счет некоторой ясности вы можете более надежно бить смарт-журнал (по крайней мере, на Q6600):

int lenHelper(unsigned x) { 
    // this is either a fun exercise in optimization 
    // or it 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 для меньших чисел - быстрее в обоих случаях, чем подход smart-log. (gcc делает более быстрый код, 0.052 для этого решения и 0.09s для подхода smart-log).

Ответ 3

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

а второй - для отрицательных чисел:

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

Ответ 4

Вы можете написать такую ​​функцию:

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

Ответ 5

длина n:

length =  ( i==0 ) ? 1 : (int)log10(n)+1;

Ответ 6

Да, используя 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

Наиболее эффективным способом может быть использование метода с быстрым логарифмом, аналогичного используемому для определения самого старшего бита, установленного в целое число.

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;
}

Эта (возможно, преждевременная) оптимизация занимает 0,65 с для 20 миллионов вызовов на моем нетбуке; итеративное деление, такое как zed_0xff, занимает 1.6 с, рекурсивное деление, такое как Kangkan, занимает 1.8 секунды, а использование функций с плавающей запятой (код Иордании Льюиса) занимает колоссальные 6.6s. Использование 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;
}

Ответ 8

Число цифр целого x равно 1 + 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));
}

Или вы можете запустить цикл для подсчета цифр самостоятельно: целое деление на 10, пока число не будет 0:

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

Вы должны быть немного осторожны, чтобы вернуть 1, если целое число 0 в первом решении, и вы также можете использовать отрицательные целые числа (работайте с -x, если x < 0).

Ответ 9

Правильная реализация snprintf:

int count = snprintf(NULL, 0, "%i", x);

Ответ 10

int digits=1;

while (x>=10){
    x/=10;
    digits++;
}
return digits;

Ответ 11

Довольно простой

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;
}

Ответ 12

sprintf(s, "%d", n);
length_of_int = strlen(s);

Ответ 13

Вы можете использовать это -

(тип_данный) log10 (имя_переменный) +-

ex:

len = (int) log10 (число) +1;

Ответ 14

продолжайте делить на десять, пока не получите нуль, а затем просто введите количество делений.

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

Ответ 15

Я думаю, что я получил самый эффективный способ найти длину целого числа его очень простой и элегантный способ вот он:

int PEMath::LengthOfNum(int Num)
{
int count = 1;  //count starts at one because its the minumum amount of digits posible
if (Num < 0)
{
    Num *= (-1);
}

for(int i = 10; i <= Num; i*=10)
{
     count++;
}      
return count;
                // this loop will loop until the number "i" is bigger then "Num"
                // if "i" is less then "Num" multiply "i" by 10 and increase count
                // when the loop ends the number of count is the length of "Num".
}

Ответ 16

На мой взгляд, самым коротким и простым решением было бы следующее:

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);

Ответ 17

Мой способ:

Разделите, если число больше не делится на 10:

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

    return i;
}

Я не знаю, насколько быстро это происходит по сравнению с другими предложениями.

Ответ 18

int intlen(int integer){
    int a;
    for(a = 1; integer /= 10; a++);
    return a;
}