![](/img/trans.png)
[英]The calculation accuracy of floating-point numbers (float, double) in Java (IEEE 754)
[英]What is the range in which IEEE754 can correctly compare the size of floating point numbers
我知道可以正確比較的整數范圍是-(2^53 - 1)
到2^53 - 1
。
但是浮點數的范圍是多少?
// Should the double type conform to this specification? I guess
double c = 9007199254740990.9;
double d = 9007199254740990.8;
System.out.println(c > d); // return false
沒有保證正確比較浮點數的特定范圍 - 這需要存在無限多的double
表示。
所有double
精度數都精確到其二進制表示的 53 位有效數字。 如果兩個數字僅在第 54 位有效二進制數字上有所不同,則它們通常具有相同的double
表示,除非四舍五入使它們不同。
這個問題似乎是基於對(數學)實數及其與 IEEE-754 的關系的基本誤解。
“浮點”是指實數的表示方案。 從歷史上看,它包括十進制數字和“小數點”。 有無限數量的實數和(相應地)無限數量的浮點數。 前提是你有足夠的紙把它們寫下來。
實數的一個特性是在任何一對不同的實數之間存在無限個實數。 這包括任何非常接近的一對。
IEEE-754 浮點數是不同的。 每個代表一個精確的實數。 對於 IEEE-754 雙精度,這些實數中有一組(小於)2^64。 不在該集合中的任何其他實數都不能精確地表示為double
。
在 Java 中,當我們這樣寫時:
double c = 9007199254740990.9;
double d = 9007199254740990.8;
System.out.println(c > d); // return false
c
的值將是最接近浮點表示法表示的實數的 IEEE-754 表示。 同樣d
。 它不會完全等於實數。 (它只能對無限實數集的有限子集是精確的......)
print 語句說明了這一點。 這 2 個實數最接近的 IEEE-754 表示是相同的。
實際發生的情況是 Java 編譯器計算出9007199254740990.9
和9007199254740990.8
含義為實數。 然后它默默地將這些數字四舍五入到最接近的 IEEE-754 double
。
所以對於你的問題:
IEEE-754可以正確比較浮點數大小的范圍是多少
A:沒有這個范圍。
如果您給我任何映射到double
值d
的實數“x”(以浮點形式表示),我可以給您寫一個也映射到相同值d
的不同實數“y”(浮點形式) . 我需要做的就是在“x”的最低有效端添加一些額外的數字。
注意:推理與 IEEE-754 的實際表示無關。 它僅取決於 IEEE-754 表示具有固定位數的事實。 這意味着可能值的集合是有界的……而 rest 是其邏輯結果。
讓我們考慮一下這些雙數的實際位表示:
我們可以使用System.out.println(Long.toBinaryString(Double.doubleToRawLongBits(c)));
打印位表示。
9007199254740990.9
和9007199254740990.8
在 IEEE 754 之后具有相同的位表示:
0 10000110011 1111111111111111111111111111111111111111111111111111
s(sign) = 0
exp = 10000110011 (binary value, which equals 1075 in decimal)
frac = 111...111 (52 bits)
此表示的精確值是:
使用 IEEE 754,從 2^53 開始,double 類型不再能夠精確表示所有大於 2^53 的整數,更不用說浮點數了。
關於 OP 問題,正如其他答案中所述,沒有准確的范圍。 例如,以下語句將評估為真。 我們不會說double可以比較的浮點數范圍小於1.1。 一般來說,數字越大,雙精度類型所能表示的精度就越低。
double x1 = 1.1;
double x2 = 1.1000000000000001;
System.out.println(x1 == x2); // true
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.