Как узнать количество символов в длинном без знака
Привет, у меня есть 2 вопроса, первый из них в названии, а другой здесь: unsigned long long это самое большое целое число (может содержать наибольшее количество символов)? потому что мне нужен int, который может содержать несколько миллионов символов (цифр) это возможно? Я пишу на C. и это связывает меня с другим вопросом: как я могу отобразить количество цифр на экране? это должно быть так?
printf("%d", intName.length)
Спасибо всем!!
4 ответа
Я предполагаю, что когда вы ссылаетесь на количество символов, вы имеете в виду количество цифр в числе. Если так, то в этом вопросе есть все, что вам нужно знать, и включен код, подобный этому
int numberOfDigits(unsigned long long n)
{
if (n == 0)
return 0;
return floor( log10( abs( n ) ) ) + 1;
}
Что касается хранения нескольких миллионов цифр, вы, вероятно, захотите изучить использование такой библиотеки, как Многофункциональная арифметическая библиотека GNU, которая включает в себя функцию
size_t mpz_sizeinbase( const mpz_t op, int base )
который скажет вам, сколько цифр имеет ваш номер.
printf("%llu", xxxxxxxxx);
the ll (el-el) long-long modifier with the u (unsigned) conversion
Вы также можете использовать
uint64_t a;
uint32_t b;
Но вам нужно включить библиотеку inttypes.h, которая предоставляет такие типы, как int32_t, int64_t, uint64_t.
Максимальная десятичная длина целого числа без знака заданного типа длины в битах bitlen
дан кем-то 1 + floor(log10(2^bitlen-1))
(математически, без учета переполнений и ошибок округления). Приближение 1/log2(10) ~ 4004.0/13301
(получено с непрерывными дробями, см. http://en.wikipedia.org/wiki/Continued_fraction) приводит к формуле 1 + bitlen * 4004 / 13301
(в вычислительном отношении, то есть деление округляется вниз). Математические детали приведены в комментариях к фрагменту ниже.
#include <limits.h>
#include <stdio.h>
/**
* Maximal number of digits in the decimal representation of an unsigned type.
*
* floor( log2(2^bitlen - 1) / log2(10) ) == floor( bitlen / log2(10) )
* otherwise an integer n would exist with
* log2(2^bitlen - 1) / log2(10) < n < bitlen / log2(10)
* log2(2^bitlen - 1) < n * log2(10) < bitlen
* 2^bitlen - 1 < 2^(n * log2(10)) < 2^bitlen
* 2^bitlen - 1 < (2^log2(10))^n < 2^bitlen
* 2^bitlen - 1 < 10^n < 2^bitlen
* which is impossible
*
* 1 / log2(10) ~ 0.301029995663981
* 4004 / 13301 ~ 0.30102999774453
*
* 1 + floor( log10(2^bitlen - 1) )
* == 1 + floor( log2(2^bitlen - 1) / log2(10) )
* == 1 + floor( bitlen / log2(10) )
* <= 1 + floor( bitlen * 4004.0 / 13301 )
* == 1 + bitlen * 4004 / 13301
* with equality for bitlen <= 13300 == 8 * 1662.5
*/
#define DECLEN(unsigned_t) (1 + CHAR_BIT*sizeof(unsigned_t) * 4004 / 13301)
int main(int argc, char *argv[]) {
printf("unsigned char : %zu\n", DECLEN(unsigned char));
printf("short unsigned : %zu\n", DECLEN(short unsigned));
printf("unsigned : %zu\n", DECLEN(unsigned));
printf("long unsigned : %zu\n", DECLEN(long unsigned));
printf("long long unsigned : %zu\n", DECLEN(long long unsigned));
return 0;
}
C99 предоставляет intmax_t (и uintmax_t), который будет наибольшим поддерживаемым целочисленным типом (обычно 64-битным.)
Предполагая, что у вас есть соответствующий C99 snprintf, вы можете получить количество цифр с помощью:
length = snprintf(NULL, 0, "%llu", value);
для значения без знака long long (и%ju для uintmax_t.)
В противном случае вам придется передать буфер в (yuk) или сделать что-то вручную, например:
length = value < 10 ? 1 :
value < 100 ? 2 :
...
также юк!
Но это все довольно неважно, если вы действительно хотите целые числа в миллион цифр, и в этом случае вам нужно будет использовать библиотеку, такую как gmp, для работы с такими большими числами.