Логарифмическое решение вычисляет неправильное количество цифр в больших целых числах

У меня недостаточно очков репутации, чтобы оставлять комментарии, но видел много раз, когда люди (неверно) предлагали использовать log10 для вычисления числа цифр в положительном целых числах. Это неверно для больших чисел!

long n = 99999999999999999L;

// correct answer: 17
int numberOfDigits = String.valueOf(n).length();

// incorrect answer: 18
int wrongNumberOfDigits = (int) (Math.log10(n) + 1); 
// also incorrect:
double wrongNumberOfDigits2 = Math.floor(Math.log10(n) + 1);

Логарифмические решения будут неправильно выводить 18 вместо 17.

Я хотел бы понять, почему.

Способ получения числа цифр в int?
Самый быстрый способ получить число цифр на номере?

Ответ 1

Проблема заключается в том, что 99999999999999999 не может быть точно представлен как значение с плавающей запятой (double precision) в этом случае. Ближайшее значение 1.0E+17 при передаче как double параметра log10.

То же самое можно сказать и о значении log10(n): 16.999999999999999995657... - ближайшее значение, которое может быть представлено, 17.

Ответ 2

Правильно математически абсолютно.

Число цифр любого целого числа, не равного нулю (положительное!), равно log10 (n) +1. Без сомнения!

Проблемы возникают с представлениями, как указывает Бретт Хейл.

Итак, если вы хотите, не проблема, нет предела, очень точный расчет:) использовать BigDecimal.

Но простейший: используйте lengthof String:

Long l=99999999999999999L;
int len=l.toString().length();

Если вы действительно хотите выполнить расчет, см.

что: Логарифм BigDecimal

что: BigDecimal для PowerDecimal на Java/Android