1.浮點數由以下三部分組成:
符號位
指數位(階碼)
尾數
2.其規范如下:
float遵從的是IEEE R32.24 ,而double 遵從的是R64.53。
需要注意到地方有: 在float 由於科學計數法都表示1.xxx 所以23位的尾碼可表示24位 ,double同理,52位尾碼實際表示53位
故在float中 符號位 1 , 指數位8 , 尾數 23位(實際表示24)
在double中 符號位1, 指數位11,尾數位 52(實際表示53)
由於 二進制並不能表示十進制所有的整數,有時只是近似表示,所以,進行類型轉換時就可能會出現數值不一致。
3.具體如何表示:
可參考如下文章:
https://zhuanlan.zhihu.com/p/63897066
https://cloud.tencent.com/developer/article/1177204
關於float 數值不一致問題,思考方式如下:
1.其實,對於浮點數,對它們進行真正的比較時使用的是機器碼,如果兩個數的機器碼完全一致,那么它們就是相等的。
1.所以,對於同一個數,它們一定是會相等的,因為即使是近似表示,它們的機器碼也都是取相同的近似值。
2.對於單浮點和雙浮點數,java對其顯示時,通常都是格式化顯示(即只顯示部分,截取型),這時你就會發現,即使拿打印出的數值和該數值比較有時也是不相等的,其原因就是打印值不等於機器碼代表的完整的值。
我們可以通過printf("%.LEGTH f", NUM) 來顯示該浮點數的完整值,也即機器碼對應的完整的值。 對於float 24尾數 1 / 2 ^24 ,所以我們應該保證從第一位非零數值起,打印出 其后9 位 小數(粗略估計哈,保證不錯),多打印幾位也沒啥,你會發現后面都是0,這樣我們看到的才是才是機器碼對應的完整的值,我們拿該打印值與原值比較也一定是相等的。
對應於 double 1 / 2^53 ,應該保證從第一位非零數值起其后打印出 17位 小數.