參考:https://cloud.tencent.com/developer/article/1473541
對於任何數字表示成二進制科學計數法以后,一定是1點幾(尾數)乘以2的多少次方(指數)。對於小於零的負數來說,就是負1點幾(尾數)乘以2的多少次方(指數)。所以要存這個數,需要存儲三個部分:正負號,尾數,指數。(尾數:二進制科學計數法中小數點后面的值,指數:2的冪)
以float類型的0.6為例:
這種二進制表示小數的方法,造成了一個隱含的問題:一些本來不是無限循環的十進制小數,表示成二進制之后成了無限循環小數。比如上圖中的十進制數字0.6,表示成二進制之后成了循環體為1001的無限循環小數。這就是“浮點數有精度問題”的根源之一,你在代碼中聲明一個變量double a = 0.6;時,計算機底層其實是無法精確存儲那個無限循環二進制數的,只能存一個四舍五入(准確說應該是零舍一入,畢竟是二進制)后的近似值,所以即引入了有效精度這一概念。
(1)對於float類型:由於尾數部分位數是固定的小數點后23位,23位所能表示的最大數是2^23−1=8388607,所以十進制的尾數部分最大數值是8388607,也就是說尾數數值超過這個值之后,float將無法精確表示,所以float最多能表示小於8388607的小數點后7位,但絕對能保證的為6位,也即float的十進制的精度為為6~7位。
(2)對於double類型:double數據類型的推算過程和上述同理,唯一的區別在於尾數由23位擴展到52位,階碼由8位增加到了11位,計算方法不變。所以double的階碼(移碼表示)為1~2046,偏移量為1023,故指數范圍為-1022~1023,得表示范圍為(2^1023*2)~(-2^1023*2)即為-1.7E+308~1.7E+308,絕對值最小可以取到2^-1022,精度則為2^52-1=4503599627370495,為16位。所以精度最高位16位,一定可以保證15位。