Java DecimalFormat показывает разные результаты для float и double - PullRequest
0 голосов
/ 07 марта 2012

почему результат отличается? Если я использую float, он получает 675, а если я использую double, я получаю 674 ... разве это не странно?

float f = 12345.6745;
double d = 12345.6745;

Locale l = Locale.forLanguageTag("es-ES");
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(l);
print(df.format(f));
>> 12.345,675

l = Locale.forLanguageTag("es-ES");
DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(l);
print(df.format(d));
>> 12.345,674

Спасибо

Ответы [ 2 ]

7 голосов
/ 07 марта 2012

Если я использую float, он получает 675, а если я использую double, я получаю 674 ... разве это не странно?

Не особенно.Вы форматируете разные значения.В частности, если вы действительно измените свой код, чтобы он компилировался (с суффиксом f для числа с плавающей точкой), даже если вы указали 9 цифр, floatбудет только достоверно представлять 7.

Ни одно из чисел не является точно 12345.6745.На самом деле, точные значения:

f = 12345.6748046875
d = 12345.674499999999170540831983089447021484375

Посмотрите на них, и очевидно, что третье десятичное место равно 5 для f и 4 для d.

Если вы хотитечтобы сохранить десятичные цифры, вы должны рассмотреть возможность использования BigDecimal.

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

Проблема, у вас есть ошибка представления.Это становится более очевидным при переполнении.

long l = 1234567890123456789L;
double d = l;
float f = l;
int i = (int) l;
short s = (short) l;
char ch = (char) l;
byte b = (byte) l;
System.out.println("l= " + l + " in hex " + Long.toHexString(l));
System.out.println("d= " + d);
System.out.println("f= " + f);
System.out.println("i= " + i + " in hex " + Integer.toHexString(i));
System.out.println("s= " + s + " in hex " + Integer.toHexString(s & 0xFFFF));
System.out.println("(int) ch= " + (int) ch +  " in hex " + Integer.toHexString(ch));
System.out.println("b= " + b +  " in hex " + Integer.toHexString(b));

печатает

l= 1234567890123456789 in hex 112210f47de98115
d= 1.23456789012345677E18
f= 1.23456794E18
i= 2112454933 in hex 7de98115
s= -32491 in hex 8115
(int) ch= 33045 in hex 8115
b= 21 in hex 15

Только long может представлять это значение без ошибок (плюс BigInteger и BigDecimal). Все остальные типы данных имеютразные ошибки.float и double точно представляют старшие биты, тогда как int, short, char и byte точно представляют младшие биты.

...