[英]Displayed precision of Java floating-point
如果我們運行以下代碼:
float f = 1.2345678990922222f;
double d = 1.22222222222222222222d;
System.out.println("f = " + f + "\t" + "d = " + d);
它打印:
f = 1.2345679 d = 1.2222222222222223
文字 1.2345678990922222 中的長尾被忽略,但 1.22222222222222222222 中的長尾不是(變量 d 中的最后一位十進制數字變為 3 而不是 2)。 為什么?
打印float
或double
float
數時看到的位數是 Java 將float
和double
float
數默認轉換為十進制數的規則的結果。
Java 對浮點數的默認格式使用將數字與附近可表示的數字區分開來所需的最少有效十進制數字。 1
在您的示例中,源文本中的1.2345678990922222f
被轉換為float
值 1.2345678806304931640625,因為在float
類型中可表示的所有值中,該值最接近 1.2345678990922222。 下一個較低和下一個較高的值是 1.23456776142120361328125 和 1.23456799983978271484375。
在打印這個值時,Java 只需要打印“1.2345679”,因為這足以讓我們從它的鄰居 1.23456776142120361328125 和 1.2345678806304931640625 中挑選出float
值 1.23456788063049316142120361328125 和 1.2984737374847373748487375
對於您的double
示例, 1.22222222222222222222d
轉換為 1.222222222222222320908713300013914704322281494140625。 接下來的下限和下一個更高的值所能表述在double
是1.2222222222222220988641083749826066195964813232421875和1.2222222222222225429533182250452227890491485595703125。 如您所見,為了將 1.22222222222222232090871330001391470432281494140625 與其鄰居區分開來,Java 需要打印“1.2222222222222223”。
1Java SE 10的規則可以在 java.lang.float 的文檔中的toString(float d)
部分找到。 double
文檔是相似的。 最相關的部分以粗體顯示的段落是:
返回
float argument
的字符串表示形式。 下面提到的所有字符都是 ASCII 字符。
如果參數為 NaN,則結果為字符串“NaN”。
否則,結果是一個字符串,表示參數的符號和大小(絕對值)。 如果符號為負,則結果的第一個字符為 '
-
' ('\-'
); 如果符號為正,則結果中不出現符號字符。 至於幅度m :
如果m為無窮大,則用字符“無窮大”表示; 因此,正無窮產生結果“Infinity”,負無窮產生結果“-Infinity”。
如果m為零,則用字符“0.0”表示; 因此,負零產生結果“-0.0”,正零產生結果“0.0”。
如果m大於或等於 10 -3但小於 10 7 ,則它表示為m的整數部分,以十進制形式表示,沒有前導零,后跟 '
.
' ('\.'
),后跟代表m的小數部分的一位或多位十進制數字。如果m小於10 -3或大於或等於10 7 ,則它以所謂的“計算機化科學記數法”表示。 令n為唯一整數,使得 10 n ≤ m < 10 n +1 ; 然后讓一個是m的精確算術商和10牛頓,使1≤然后<10的大小被表示為a的整數部分,作為一個單一的十進制數字,后跟'
.
“('\.'
),再后面是表示一個小數部分十進制數字,后面跟有字母”E
'('\E'
),接着為十進制整數n的表示,作為由該方法制備Integer.toString(int)
。m或a的小數部分必須打印多少位數字? 必須至少有一個數字來表示小數部分,並且超過這個數字,但只能是唯一地將參數值與相鄰的
float
類型值區分開來所需的數字。 也就是說,假設x是由此方法為有限非零參數f生成的十進制表示所表示的精確數學值。 那么f必須是最接近x的float
值; 或者,如果兩個float
值同樣接近x ,則f必須是其中之一,並且f的有效數的最低有效位必須為 0。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.