Зачем парсинг double в Java создал новые числа? - PullRequest
1 голос
/ 07 марта 2011

После запуска следующих строк:

double d=Float.parseFloat("9.99");
System.out.println(""+d);

Я получил это: 9.989999771118164

Я ожидал увидеть: 9.99

Почему и как это исправить?

============================================================

Редактировать: я должен был использовать: double d = Double.parseDouble ("9.99"), который печатает 9.99.Это моя вина, но интересно посмотреть подробные ответы, спасибо!

Ответы [ 5 ]

14 голосов
/ 07 марта 2011

Если вам нужны точные десятичные значения, используйте BigDecimal.В противном случае узнайте, как работает двоичная система с плавающей запятой, и будьте готовы справиться с последствиями.(Конечно, даже BigDecimal не сможет точно представить что-то вроде «третьего».)

Обратите внимание, что довольно странно вызывать Float.parseFloat, но присваивать результат double... было бы более привычным либо присвоить результат float или , чтобы использовать Double.parseDouble для начала.Однако в любом случае результат будет , а не точно равным 9,99.Число 9.99 не может быть представлено в двоичной форме с плавающей запятой точно так же, как результат деления один на три может быть записан точно в десятичном представлении.

У меня нет статей о двоичной двоичной переменной с плавающей запятой Javaв частности, но не должно быть никаких существенных различий между этим и двоичной плавающей точкой C #, которую я делаю имею статью о .

Какой тип выСледует использовать действительно зависит от семантики того, что вы представляете.Я использую эмпирическое правило, согласно которому искусственные «искусственные» значения, такие как деньги, лучше всего представлять в десятичных форматах (например, BigDecimal), тогда как «естественные» значения, такие как высота и ширина, более подходят как float / double.

4 голосов
/ 07 марта 2011

Число 9.99 нельзя представить точно как число с плавающей запятой, поэтому Float.parseFloat вернул ближайший представимый номер с плавающей запятой.

Для получения дополнительной информации выполните поиск по запросу ", что должен знать каждый компьютерщик об арифметике с плавающей точкой " в Google.

2 голосов
/ 07 марта 2011

Это не имеет ничего общего с Java.Это связано с представлением с плавающей запятой.Если вы хотите представить число как две десятичные десятичные числа с плавающей точкой, я предлагаю вам использовать printf или String.format:

System.out.println(String.format("%.2f", 9.99));

Regards

1 голос
/ 07 марта 2011

Числа с плавающей запятой по-прежнему представлены битами, которые имеют ограниченное число возможных конфигураций, поэтому даже числа с плавающей запятой являются дискретными (они не могут представлять значения с произвольной точностью и происходит округление).Здесь вы наблюдаете неточность с плавающей запятой, 9,99 не может быть точно представлено типом данных.Как вы «исправите» это зависит от того, что вы хотите сделать.

0 голосов
/ 07 марта 2011

Если вы попробуете Double.parseDouble(), вы получите ожидаемый результат.

...