Вы достигли максимальной точности для double
с этим числом.Это не может быть сделано.В этом случае значение округляется.Преобразование из BigDecimal
не связано, и проблема точности одинакова в любом случае.Посмотрите на это, например:
System.out.println(Double.parseDouble("299792.4579999984"));
System.out.println(Double.parseDouble("299792.45799999984"));
System.out.println(Double.parseDouble("299792.457999999984"));
Вывод:
299792.4579999984
299792.45799999987
299792.458
В этих случаях double
имеет более 3 цифр точности после десятичной точки.Они просто являются нулями для вашего номера, и это самое близкое представление, которое вы можете поместить в double
.В этом случае это ближе к округлению, поэтому ваши 9, кажется, исчезают.Если вы попробуете это:
System.out.println(Double.parseDouble("299792.457999999924"));
Вы заметите, что он сохраняет ваши 9, потому что он был ближе к округлению вниз:
299792.4579999999
Если вам требуется все цифр в вашем номере будет сохранено, тогда вам придется изменить код, который работает на double
.Вы могли бы использовать BigDecimal
вместо них.Если вам нужна производительность, вы можете использовать BCD в качестве опции, хотя я не знаю ни о каких библиотеках.
В ответ на ваше обновление: максимальный показатель степенидля числа с плавающей точкой двойной точности на самом деле 1023. Это не ваш ограничивающий фактор, хотя здесь.Ваше число превышает точность 52 дробных битов, которые представляют значение, см. IEEE 754-1985 .
Используйте это преобразование с плавающей запятой , чтобы увидеть ваше число вдвоичный файл.Показатель степени равен 18, поскольку 262144 (2 ^ 18) является ближайшим.Если вы возьмете дробные биты и увеличите или уменьшите один в двоичном виде, вы увидите, что для представления вашего числа недостаточно точности:
299792.457999999900 // 0010010011000100000111010100111111011111001110110101
299792.457999999984 // here's your number that doesn't fit into a double
299792.458000000000 // 0010010011000100000111010100111111011111001110110110
299792.458000000040 // 0010010011000100000111010100111111011111001110110111