關於float相減精度丟失的問題

2021-08-01 17:30:37 字數 1038 閱讀 1479

小數的二進位制表示問題

首先我們要搞清楚下面兩個問題:

(1) 十進位制整數如何轉化為二進位制數

演算法很簡單。舉個例子,11表示成二進位制數:

11/2=5 餘   1

5/2=2   餘   1

2/2=1   餘   0

1/2=0   餘   1

0結束         11二進位制表示為(從下往上):1011

這裡提一點:只要遇到除以後的結果為0了就結束了,大家想一想,所有的整數除以2是不是一定能夠最終得到0。換句話說,所有的整數轉變為二進位制數的演算法會不會無限迴圈下去呢?絕對不會,整數永遠可以用二進位制精確表示,但小數就不一定了。

(2) 十進位制小數如何轉化為二進位制數

演算法是乘以2直到沒有了小數為止。舉個例子,0.9表示成二進位制數

0.9*2=1.8   取整數部分 1

0.8(1.8的小數部分)*2=1.6    取整數部分 1

0.6*2=1.2   取整數部分 1

0.2*2=0.4   取整數部分 0

0.4*2=0.8   取整數部分 0

0.8*2=1.6 取整數部分 1

0.6*2=1.2   取整數部分 0

.........      0.9二進位制表示為(從上往下): 1100100100100......

注意:上面的計算過程迴圈了,也就是說*2永遠不可能消滅小數部分,這樣演算法將無限下去。很顯然,小數的二進位制表示有時是不可能精確的。其實道理很簡單,十進位制系統中能不能準確表示出1/3呢?同樣二進位制系統也無法準確表示1/10。這也就解釋了為什麼浮點型減法出現了"減不盡"的精度丟失問題。

解決辦法:

bigdecimal b1 = new bigdecimal(float.tostring(xx));

bigdecimal b2 = new bigdecimal(float.tostring(yy));

float ss = b1.subtract(b2).floatvalue(); 

關於float的精度型別

1 主要記錄一下為什麼float的精度型別為6 7位 首先,應該明確float資料型別,佔4個位元組,共4 8 32位,其中 ieee754標準規定如下 32位當中,1位為符號位 8位指數字 23位為數值位。故float型別的數值是由後邊的23位決定。23位指的是2進製數可以表示2 23取值範圍以內...

解決double和float精度不准的問題

float和double型,的底層實現是二進位制的。十進位制中的乙個有限位數小數,轉換成二進位制就不一定是有限位數了,一旦位數超過的float和double型的位數寬度,就會出現 精度溢位 所以float和double型是為了科學計算而設計的,並不適合精確的十進位制計算.就像乙個十進位制的小數,要不...

解決double和float精度不准的問題

float和double型,的底層實現是二進位制的。十進位制中的乙個有限位數小數,轉換成二進位制就不一定是有限位數了,一旦位數超過的float和double型的位數寬度,就會出現 精度溢位 所以float和double型是為了科學計算而設計的,並不適合精確的十進位制計算.就像乙個十進位制的小數,要不...