Я хотел бы знать, как я могу найти длину целого числа в C.
Например:
- 1 => 1
- 25 => 2
- 12512 => 5
- 0 => 1
и так далее.
Как я могу сделать это на C?
Я хотел бы знать, как я могу найти длину целого числа в C.
Например:
и так далее.
Как я могу сделать это на 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
.
Кроме того, вы можете добавить единицу к окончательному результату, если ввод отрицательный, если вас интересует длина числа, включая его отрицательный знак.
int nDigits = Math.floor(Math.log10(Math.abs(the_integer))) + 1;
N.B. Из-за того, что в этом методе используются вычисления с плавающей запятой, он может быть медленнее, чем при более прямом подходе. См. Комментарии к ответу Кангкана для обсуждения эффективности.
int
, только целое число.
- person chqrlie; 24.11.2015
== 0
, вот однострочник: (the_integer == 0 ? 1 : (int)floor(log10(abs(the_integer))) + 1)
- person luckydonald; 22.11.2016
long long nDigits = floor(log10(llabs(the_integer))) + 1;
- person protoEvangelion; 27.03.2017
Если вас интересует быстрое и очень простое решение, наиболее быстрым может быть следующее (это зависит от распределения вероятностей рассматриваемых чисел):
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 и ниже смарт-журнал работает быстрее.
За счет некоторой наглядности можно более надежно обыграть smart-log (по крайней мере, на 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 с для подхода с умным журналом).
s branch prediction and not produce the fastest execution I
m.
- person Lloyd Crawley; 23.10.2013
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;
}
Вы можете написать такую функцию:
unsigned numDigits(const unsigned n) {
if (n < 10) return 1;
return 1 + numDigits(n / 10);
}
if ( x < 0 ) return 1 + printed_length ( -x );
в начало
- person Pete Kirkham; 18.06.2010
1 +
перестает быть банальным хвостовым вызовом.
- person Pete Kirkham; 18.06.2010
длина n:
length = ( i==0 ) ? 1 : (int)log10(n)+1;
casting
реализовано? как можно реализовать такую функцию, как пол? (мы предполагаем, что процессор с ieee в аппаратном обеспечении, или через математический сопроцессор, или доступность программной функции для выполнения той же функции, которая обычно присутствует на процессорах с поддержкой FP) ... в конце (int) является переносимым и согласованным в в большинстве случаев (осмелюсь сказать, во всех случаях, о которых мы обычно заботимся)
- person ShinTakezou; 18.06.2010
Количество цифр целого числа 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
).
do
цикл.
- person chux - Reinstate Monica; 24.11.2015
Наиболее эффективным способом могло бы быть использование подхода, основанного на быстром логарифме, аналогичного тем, которые используются для определения наивысшего набора битов в целых числах.
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,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;
}
snprintf()
, почему бы не snprintf(NULL, 0, "%d", x)
и ничего не писать? (По крайней мере, используйте в своей функции статический буфер.)
- person Chris Lutz; 18.06.2010
INT_MIN
. Используйте для тестов локальную unsigned
переменную и инициализируйте ее с помощью x >= 0 ? x : -(unsigned)x
- person chqrlie; 24.11.2015
Правильная snprintf
реализация:
int count = snprintf(NULL, 0, "%i", x);
count
будет иметь одну дополнительную единицу для знака минус.
- person sam hocevar; 30.01.2016
Да, используя 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++;
}
snprintf()
, чтобы вам не пришлось ничего писать (и рисковать переполнением).
- person Chris Lutz; 18.06.2010
sprintf()
без вызова strlen()
- person phuclv; 14.03.2015
В этой задаче я использовал арифметическое решение. Спасибо :)
int main(void)
{
int n, x = 10, i = 1;
scanf("%d", &n);
while(n / x > 0)
{
x*=10;
i++;
}
printf("the number contains %d digits\n", i);
return 0;
}
Вы можете использовать это -
(тип_данных) log10 (имя_переменной) +1
ex:
len = (int) log10 (число) +1;
Довольно просто
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;
}
делите на десять, пока не получите ноль, а затем просто выведите количество делений.
int intLen(int x)
{
if(!x) return 1;
int i;
for(i=0; x!=0; ++i)
{
x /= 10;
}
return i;
}
Это касается как отрицательных, так и положительных результатов.
int get_len(int n)
{
if(n == 0)
return 1;
if(n < 0)
{
n = n * (-1); // if negative
}
return log10(n) + 1;
}
Та же логика и для цикла
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;
}
Почему бы вам не преобразовать целое число в String и не получить такую длину:
int data = 123;
int data_len = String(data).length();
На мой взгляд, самым коротким и простым решением было бы:
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);
do...while
, чтобы цикл выполнялся один раз, когда (n) равно 0.
- person Kevin Fegan; 11.01.2014
Мой метод:
Разделите, пока число не делится на 10:
u8 NumberOfDigits(u32 number)
{
u8 i = 1;
while (number /= 10) i++;
return i;
}
Я не знаю, насколько это быстро по сравнению с другими предложениями ..
Более подробным способом было бы использовать эту функцию.
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;
}
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 // он будет считаться - также как один символ, если вы не хотите считать минус, удалите счетчик ++ из 5-й строки.
566666 -> 6
0 -> 1
505 -> 3
Я думаю, что у меня есть наиболее эффективный способ найти длину целого числа, это очень простой и элегантный способ:
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".
}
Num *= (-1)
кажется немного тяжеловесным, хотя ваш компилятор, вероятно, оптимизирует его до гораздо более эффективного Num = -Num
. Обратите внимание, что умножение часто бывает дорогостоящей операцией, тогда как отрицание целого числа довольно тривиально.
- person Arunas; 10.10.2013
int32_t
.
- person chqrlie; 24.11.2015
int main (void) {unsigned int n, размер = 0;
printf("get the int:");
scanf("%u",&n);
/*the magic*/
for(int i = 1; n >= i; i*=10){
size++;
}
printf("the value is: %u \n", n);
printf("the size is: %u \n", size);
return 0;
}
Пожалуйста, найдите мой ответ в однострочном коде:
#include <stdio.h>
int main(void){
int c = 12388884;
printf("length of integer is: %d",printf("%d",c));
return 0;
}
это просто и умно! Проголосуйте, если вам это нравится!
log10(10000)
вернет 4, а не 3.999999 ...? - person Keith Thompson   schedule 29.08.2011log10(10**n)
дает точное значение для степеней 10 от 1 до 2 ** 19, по крайней мере, с gcc и glibc. Но я бы не стал рассчитывать на это для всех реализаций. (**
обозначает возведение в степень; в C. нет такого оператора) - person Keith Thompson   schedule 29.08.2011