2012-02-13 1 views
1

я пытаюсь проценты формата с помощью следующего кода:Формат дробно процента в ява доходности очень странное поведение

NumberFormat fmt = NumberFormat.getPercentInstance(); 
fmt.setRoundingMode(RoundingMode.HALF_UP); 
fmt.setMinimumFractionDigits(0); 
fmt.setMaximumFractionDigits(0); 
System.out.println(fmt.format(0.145)); 

Однако, я получаю очень странный результат:

14%

Изменение значения 0.145 на что-то другое, например 0.125 будет работать правильно, и результат будет таким, как ожидалось

13%

Может кто-то пролить свет на это? Заранее спасибо

ответ

1

Это связано с присущей ошибки округления в double, в результате чего 0.145 округляется до

0.1449999999999999900079927783735911361873149871826171875 

Используйте BigDecimal, если вы ожидаете совершенной точности.

+0

Из любопытства, почему это не так для 0.125? – kosa

+0

Поскольку значение 0.125 может быть точно представлено как дробное число в двоичном формате, так как оно равно '1/8'. –

+0

Получил это. Имеют смысл. Благодаря! – kosa

1

Я думаю, что это результат внутреннего представления поплавков. (Десятичные числа, представленные двоичными числами).

Ваш 0.145 может быть внутренне представлен как 0.144999999999 ..., поэтому округление округляется вниз.

1

Вы должны прочитать What Every Computer Scientist Should Know About Floating-Point Arithmetic, но в основном это сводится к тому, что .145 не может быть точно представлено в плавающей точке IEEE и поэтому округляется до ближайшего значения, которое может быть представлено, что просто немного меньше, чем .145, поэтому округляется до округлых до двух цифр.