Количество цифр, которое вы видите при печати float
или double
, является следствием правил Java для преобразования по умолчанию float
и double
в десятичное число.
Форматирование Java по умолчаниюдля чисел с плавающей запятой используется наименьшее количество значащих десятичных цифр, необходимое для различения числа от ближайших представляемых чисел. 1
В вашем примере 1.2345678990922222f
в исходном тексте преобразуется в float
значение 1.2345678806304931640625, поскольку из всех значений, представленных в типе float
, это значение наиболее близко к 1.2345678990922222.Следующие более низкие и следующие более высокие значения - это 1,23456776142120361328125 и 1,23456799983978271484375.
При печати этого значения Java нужно вывести только «1,2345679», потому что этого достаточно, чтобы мы могли выбрать значение float
1,2345678806304931640625 у его соседей1.23456776142120361328125 и 1.23456799983978271484375.
Для вашего double
примера, 1.22222222222222222222d
преобразуется в 1.22222222222222232090871330001391470432281494140625.Следующие более низкие и следующие более высокие значения, представленные в double
, представляют собой 1,2222222222222220988641083749826066195964813232421875 и 1,2222222222222225429533182250452227890491485595703125.Как вы можете видеть, чтобы отличать 1.22222222222222232090871330001391470432281494140625 от соседей, Java необходимо вывести «1.2222222222222223».
Сноска
1 Правило Java SE 10 можно найти в документации по java.lang.float, в разделе toString(float d)
.Документация double
аналогична.Отрывок с наиболее релевантной частью, выделенной жирным шрифтом, выглядит так:
Возвращает строковое представление float argument
.Все упомянутые ниже символы являются символами ASCII.
Если аргумент равен NaN, результатом является строка "NaN".
В противном случаеРезультатом является строка, которая представляет знак и величину (абсолютное значение) аргумента.Если знак отрицательный, первым символом результата будет '-
' ('\u002D'
);если знак положительный, знак не появляется в результате.Что касается величины м :
Если м - бесконечность, то она представлена символами «Бесконечность»;таким образом, положительная бесконечность дает результат «Бесконечность», а отрицательная бесконечность - «-Infinity».
Если m равно нулю, то оно представлено символами"0.0";таким образом, отрицательный ноль дает результат "-0.0", а положительный ноль дает результат "0.0".
Если m больше или равно 10 -3 , но меньше 10 7 , тогда он представляется как целая часть m , в десятичной форме без начальных нулей, за которыми следует '.
'('\u002E'
), за которым следуют одна или несколько десятичных цифр, представляющих дробную часть m .
Если m меньше 10 -3 или больше или равно 10 7 , тогда оно представлено в так называемой "компьютеризированной научной нотации".Пусть n будет уникальным целым числом таким, что 10 n ≤ m <10 <sup> n + 1;тогда пусть a будет математически точным отношением m и 10 n , так что 1 ≤ a <10Затем величина представляется как целая часть <em>a , как одна десятичная цифра, за которой следует '.
' ('\u002E'
), за которой следуют десятичные цифры, представляющие дробную часть a , за которым следует буква 'E
' ('\u0045'
), за которой следует представление n в виде десятичного целого числа, полученного методом Integer.toString(int)
.
Сколькоцифры должны быть напечатаны для дробной части m или a ? Должна быть хотя бы одна цифра для представления дробной части, и помимо этого столько, но только столько, сколько цифр необходимо для уникального различия значения аргумента от смежных значений типа float
. То есть предположим, что x является точным математическим значением, представленным десятичным представлением, полученным этим методом для конечного ненулевого аргумента f .Тогда f должно быть значением float
, ближайшим к x ;или, если два значения float
одинаково близки к x , тогда f должно быть одним из них, а младший значащий бит из значения f долженбыть 0.