JAVA浮點數的范圍 和精度


本篇先介紹IEEE754標准中針對浮點數的規范,然后以問答形式補充有關浮點數的知識點。

 

(一)IEEE754標准

IEEE 754 標准即IEEE浮點數算術標准,由美國電氣電子工程師學會(IEEE)計算機學會旗下的微處理器標准委員會發布。

 

以32位float數據為例,在內存中的存儲形式是1bit的符號位(S),8bit表示指數部分(Exp),23表示小數部分的尾數(Fraction)。

表一 單精度浮點數在內存中存儲形式

1bit符號

8bit指數部分

23bit尾數

符號位——S取0時表示負數,取1時表示負數。

指數部分——使用所謂的偏正值形式表示,而不是補碼表示,即指數部分采用一個無符號的正數值存儲。也就是說指數部分要表示的值等於實際存儲值減去一個固定值(對於單精度float類型,是127)。采用這種方式表示的目的是簡化比較,因為,如果采用補碼表示的話,全體符號位S和Exp自身的符號位將導致不能簡單的進行大小比較。因為指數值的大小從0~255(0和255是特殊值),單精度的指數部分范圍是-127~+128(對應的,-127和128是特殊值)。

尾數部分——23bit尾數僅能表示小數部分的尾數,小數部分最高有效位由指數部分決定,具體見下表。小數部分最高有效位是1的數被稱為正規形式。小數部分最高有效位是0的數被稱為非正規形式,其他情況是特殊值。

表二 單精度浮點數表示規則

符號

指數

部分

指數部分-127

尾數部分

小數部分的

最高有效位

形式

1

255

128

非0

沒有

NaN

1

255

128

0

沒有

負無窮

1

1~254

-126~127

任意

1

正規形式(負數)

1

0

-127

非0

0

非正規形式(負數)

1

0

-127

0

沒有

負0

0

0

-127

0

沒有

正0

0

0

-127

非0

0

非正規形式(正數)

0

1~254

-126~127

任意

1

正規形式(正數)

0

255

128

0

沒有

正無窮

0

255

128

非0

沒有

NaN

按照IEEE標准,除了 NaN 以外,浮點數集合中的所有元素都是有序的。如果把它們從小到大按順序排列好,那順序將會是:負無窮,正規形式(負數)、非正規形式(負數)、負0、正0、非正規形式(正數)、正規形式(正數)、正無窮。

 

對於64bit的雙精度double類型,在內存中的存儲形式是1bit的符號位(S),11bit表示指數部分(Exp),52bit表示小數部分的尾數(Fraction)。指數部分的偏正值是1023,其他情況跟單精度類似,不再贅述。

(二)浮點數Q&A

1)浮點數可以表示數據的范圍是什么?

不考慮特殊值(無窮大、NaN等),浮點數可以表示的范圍是[-Max,Max]。其中Max是浮點數能表示的最大值,具體值參見表三。

表三 浮點數最大值

浮點類型

字節碼

16進制表示

10進制表示

單精度

7f7fffff

0x1.fffffep127

3.4028235E38

雙精度

7fefffffffffffff

0x1.fffffffffffffp1023

1.7976931348623157E308

 

2)浮點數的精度怎樣衡量?

浮點數指數部分Exp的數值決定了浮點數與相鄰浮點數的差值,所以,指數部分越小(單精度最小為-127),即浮點數絕對值越小(也就是浮點數越靠近0),相鄰浮點數的差值越小(單精度最小為2^(-127)),浮點數能表示的有效小數位數越多。反之,指數部分越大(單精度最大為127),即浮點數絕對值越大(也就是浮點數越遠離0),相鄰浮點數的差值越大(單精度最小為2^(127)),浮點數能表示的有效小數位數越少。但是,從科學計算的角度看,不管指數部分的數值是多少,浮點數的有效位數由尾數部分決定,單精度的有效數是7位,雙精度的有效數是16位。

表四 浮點數最小正數

浮點類型

字節碼

16進制表示

10進制表示

單精度最小正數

00000001

0x0.000002p-126

1.4E-45

雙精度最小正數

0000000000000001

0x0.0000000000001p-1022

4.9E-324

3)我們知道,在Java中,存在基本數據類型的自動轉換,比如,直接將一個整形字面量賦給一個float變量。 那么,在自動轉換后,整形的精度會丟失么?

當浮點集中沒有與整形值對應的浮點數時,會將整形值轉化成最接近的浮點值,此時,整形值會丟失精度。例如下面的例子,數值為33554431的整形轉化成單精度浮點數后,變成3.3554432E7,即33554432。

int intValue = Integer.MAX_VALUE >> 6;// 33554431

float floatFromInt = intValue;

System.out.println(floatFromInt);// 3.3554432E7

System.out.println(intValue);// 33554431

 

最后附查看某些浮點數字節碼、16進制表示、10進制表示的源碼及運行結果。

單精度源碼及結果。 

  Float

3.3554432E7
33554431
描述           十六進制數                       字節碼             十進制數    
正        無         窮 Infinity            7f800000    Infinity            
最        大         值 0x1.fffffep127      7f7fffff    3.4028235E38        
最小正規形式正數     0x1.0p-126          00800000    1.17549435E-38      
最大非正規形式值     0x0.8p-126          00400000    5.877472E-39        
最    小      正    數 0x0.000002p-126     00000001    1.4E-45             
負         無        窮 -Infinity           ff800000    -Infinity           
規     范     的 NaN NaN                 7fc00000    NaN                 
其     他     的 NaN NaN                 ffc54321    NaN                

雙精度源碼及結果。 

  Double

描述           十六進制數                                           字節碼                                      十進制數 
正        無         窮 Infinity                      7ff0000000000000        Infinity                                
最        大         值 0x1.fffffffffffffp1023        7fefffffffffffff        1.7976931348623157E308                  
最小正規形式正數     0x1.0p-1022                   0010000000000000        2.2250738585072014E-308                 
最大非正規形式值     0x0.8p-1022                   0008000000000000        1.1125369292536007E-308                 
最    小      正    數 0x0.0000000000001p-1022       0000000000000001        4.9E-324                                
負         無        窮 -Infinity                     fff0000000000000        -Infinity                               
規     范     的 NaN NaN                           7ff8000000000000        NaN                                     
其     他     的 NaN NaN                           fff8000000054321        NaN                                    

參考資料:

1、IEEE754百度百科

2、《Java虛擬機規范(Java SE 7)》

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM