Float計算機表示形式


float為什么比int表示的范圍廣?

什么是單精度和雙精度?

float表示小數的時候為什么會有精度丟失?

帶着這幾個問題,我們來探究下javafloat類型在計算機的表示形式。

javaint占用4個字節,float也是占用4個字節,但是為什么float表示的范圍要比int大呢,因為兩者在計算機內中表示的方式不一樣,int4個字節32位,每一位都是二進制小數表示,最高位0代表是正數,最高位為1代表是負數,所以int的范圍是-2^31~2^31-1;

float也是4個字節,遵循IEEE-754格式標准,在計算機中表示有三個部分組成:符號s底數m和指數e

 

符號s最高位,0為正數;1為負數,占用一位;

指數e是該浮點數的指數,二進制表示,最高位為指數符號為1表示大於10表示小於1其實他是用的偏移量表示的,偏移大小為127,沒有用補碼表示,占用一個字節8

底數m是該浮點數的實際值,二進制形式表示,m的范圍是【12】或者【01】占用23位。

所以float在計算機的表示如下面所示:

SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM

 

我們先說下10進制和二進制的快速轉換方法。

10進制整數2進制轉換是除2求商和余數,比如十進制17的二進制計算為:

17 /2=161

16 /2= 8 0

8 /2= 4 0

4 /2= 2 0

2 /2= 1 0

1 /2= 0 1

一直計算到商為0為止,17的二進制表示就是:10001

 

10進制小數2進制表示是乘2求積,比如0.16的二進制計算為:

0.16*2=0.320

0.32*2=0.640

0.64*2=1.281

0.28*2=0.560

0.56*2=1.121

0.12*2=0.240

。。。

所以0.16的二進制表示就是001010..... 一直循環下去,所以除非小數最后為5才能*2取整,否則都會無線循環下去,這就是為什么浮點小數精度丟失的問題。

 

下面我們距離來說明10進制浮點數在計算機的表示, 拿17.16來說:

1.首先為正數,s0

2.二進制為10001.0010100011110101....小數點左移4位為1.00010010100011110101...

3.指數位為4+127=10000011,所以指數位位10000011

4.由於默認最左邊為1,所以底數為00010010100011110101...

5.最后17.16的二進制表示就是:01000001100010010100011110101......總共32位,后面的舍棄

 

再拿0.16舉例:

1.首先為整數,s0

2.二進制為0.0010100011110101......小數點右移4位為1.0100011110101

3.指數位為4+127=10000011,然后取反為01111100,所以指數位位01111100

4.底數位0100011110101...

5.最后0.16的二進制表示就是:0011111000100011110101...

 

float的(正數)范圍:

最小值:Float.MIN_VALUE=1.4E-45 2-149次方:指數位127+底數22
最大值:Float.MAX_VALUE=3.4028235E38 2128次方-1

float是單精度浮點數,4個字節;double是雙精度浮點數,8個字節,e占11位,m占52位。

 

注意事項:

1.價格在數據庫中保存建議是無符號整形,避免在java轉換成浮點數時出現精度丟失的問題;

2.如果需要用浮點型數據進行運算,建議使用BigDecimal,但是BigDecimal的構造函數一定要使用字符串的,否則一樣會出現精度丟失的問題:BigDecimal(“123f”)而不是BigDecimal(123f)

3.Float.MIN_VALUE是:1.4E-45,不是一個負數,double也是的。但是整型的MIN_VALUE都是負數

4.floatm只有23位,2^23=8388608,總共有710進制數字,由於最左邊的1省略了,所以表示的有效數字最高精確度位78位,包括整數部分,8位后的數字肯定不是准確的


免責聲明!

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



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