В приложении, в котором я работаю, некоторые числа преобразуются и сохраняются из длинных (18 цифр) в числа с плавающей запятой / удвоением. Эти числа аналогичны ссылкам / идентификаторам, но не используются для расчетов. Недавно я заметил некоторые несоответствия в данных, хранящихся как float / double. Я пытаюсь понять, связано ли это поведение с тем, что числа с плавающей запятой называют значащими цифрами, и, возможно, с простым объяснением того же.
Мои вопросы по программе ниже:
- Выход №: 5 показывает действительно большое число (39 цифр до десятичной дроби) как максимальное значение с плавающей запятой. Почему тогда float не может точно отображать что-либо, превышающее 7 цифр. Это потому, что он поддерживает только 6-7 значащих цифр.
- Выходной номер 10 показывает действительно большое число как максимальное значение double. Почему тогда double не может точно отображать что-либо, превышающее 16 цифр. Это потому, что он поддерживает только 15 значащих цифр.
- Что на самом деле подразумевается под значащими цифрами? Означает ли это, что любые цифры после этого числа не будут представлены точно, независимо от того, стоит ли оно до или после десятичной точки?
ПРИМЕЧАНИЕ. После исследования этой темы я понял, что числа с плавающей запятой по своей природе неточны и не должны использоваться для представления вещей, требующих точного представления. Тем не менее я немного смущен приведенным выше поведением и значащими цифрами.
public class Main
{
public static void main(String[] args) {
System.out.printf( "1. Float value of 50000000115 is : %,f. Expected output was 50000000115.000000 \n", 50000000115f );
System.out.printf( "2. Float value of 50000000116 is : %,f. Expected output was 50000000116.000000 \n", 50000000116f );
System.out.printf( "3. Float value of 50000000117 is : %,f. Expected output was 50000000117.000000 \n\n", 50000000117f );
System.out.printf( "4. Float value of 2175863596593954381 is : %,f. Expected output was 2175863596593954381.000000 \n\n", 2175863596593954381f );
System.out.printf( "5. Float.MAX_VALUE: %,f\n\n", Float.MAX_VALUE );
System.out.printf( "6. Double value of 50000000115 is : %,f\n", 50000000115d );
System.out.printf( "7. Double value of 50000000116 is : %,f\n", 50000000116d );
System.out.printf( "8. Double value of 50000000117 is : %,f\n\n", 50000000117d );
System.out.printf( "9. Double value of 2175863596593954381 is : %,f. Expected output was 2175863596593954381.000000 \n\n", 2175863596593954381d );
System.out.printf( "10. Double.MAX_VALUE: %,f\n\n", Double.MAX_VALUE );
System.out.printf( "11. Float value of number gives expected result till 7 digits ie 12345678 is : %,f\n", 12345678f );
System.out.printf( "12. Float value of number gives expected result till 7 digits ie 11111111 is : %,f\n", 11111111f );
System.out.printf( "13. Double value of number gives expected result till 16 digits ie 1122334455667788 is : %,f\n", 1122334455667788d );
System.out.printf( "14. Double value of number gives expected result till 16 digits ie 1111222233334444 is : %,f\n", 1111222233334444d );
}
}
Вывод вышеуказанной программы
- Плавающее значение 50000000115 составляет: 49 999 998 976,000000. Ожидаемый результат был 50000000115.000000.
- Плавающее значение 50000000116 составляет: 49 999 998 976,000000. Ожидаемый результат: 50000000116.000000.
Плавающее значение 50000000117 составляет: 49 999 998 976,000000. Ожидаемый результат: 50000000117.000000.
Плавающее значение 2175863596593954381 составляет: 2,175,863,554,941,386,750,000000. Ожидаемый выпуск 2175863596593954381000000
Float.MAX_VALUE: 340,282,346,638,528,860,000,000,000,000,000,000,000,000000
Двойное значение 50000000115: 50,000,000,115,000000
- Двойное значение 50000000116: 50,000,000,116,000000
Двойное значение 50000000117: 50,000,000,117,000000
Двойное значение 2175863596593954381: 2,175,863,596,593,954,300,000000. Ожидаемый результат: 2175863596593954381.0 00000
Double.MAX_VALUE: 179,769,313,486,231,570,000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Число с плавающей запятой дает ожидаемый результат до 7 цифр, т.е. 12345678: 12,345,678.000000
- Число с плавающей запятой дает ожидаемый результат до 7 цифр, т.е. 11111111: 11,111,111.000000
- Двойное значение числа дает ожидаемый результат до 16 цифр, т.е. 1122334455667788: 1,122,334,455,667,788.000000
- Двойное значение числа дает ожидаемый результат до 16 цифр, т.е. 1111222233334444: 1,111,222,233,334,444.000000
BigDecimal
и возможно, такжеBigInteger
… - person deHaar   schedule 16.09.2019System.out.println(0.1+0.2)
- person user85421   schedule 16.09.2019