包裝類Float中爲何有兩個常量來表示最小值

1)問:包裝類Float中爲何有兩個常量來表示最小值:MIN_VALUE和MIN_NORMAL數組

① MIN_VALUE:最小正非零值常量,是非規格化浮點數所能表示的最小值。值爲 3.4E-45 的常量。編碼

② MIN_NORMAL:最小正標準值常量,是規格化浮點數所能表示的最小值,即 2^-126。spa

能夠看出,定義中「格式化」是MIN_VALUE和MIN_NORMAL ,不一樣的關鍵因素。code

分析:orm

在計算機中浮點數是由符號,指數和尾數組成。對象

同一個數字能夠有多種表達方式111.11能夠表示爲1.1111*10^2也能夠表示爲0.11111*10^3,計算機要進行計算處理就必需要有固定的表達方式,不然計算起來會很影響效率,所以須要規劃範表示浮點數,規範化之後表示爲±1.f×2E−127,f是尾數,E是指數,因爲整數部分固定爲1,因此能夠省略。blog

以單精度爲例,指數位爲8位,尾數位爲23位,因爲整數部分1固定23位的尾數能夠表示24位,因此能夠得出結論:ci

一個int值從第一個1到最後一個1爲止的位數超過24,則該值不能被float精確表示。form

由於指數部分爲了表示負數,因此採用偏移值的編碼方式,將8位255一分爲二,[ 1,127 ) 是負數,[ 127, 254 ] 是正數,0和255有特殊用途。因此最小的正規化表示爲2^-126也就是MIN_NORMAL。class

因爲在指數運算中可能出現的浮點數對應的指數小於-126,致使沒法進行規範化保存,若是按規範化去表示,可能致使一個非零值變爲零值,爲了解決這種問題,IEEE 標準中引入了非規範(Denormalized)浮點數。規定當浮點數的指數爲容許的最小指數值,尾數沒必要是規範化的,這樣能夠保存更小的尾數,MIN_VALUE爲能保存到的最小的非零值,就是MIN_NORMAL*2-23,也就是尾數1右移23位。

2)問:double a = 1.0-0.9的結果不精確等於0.1,爲何?

浮點數在計算機中進行加減運算時,須要通過零值檢測、對階操做、尾數求和、規格化操做等操做,精度可能丟失。

float和double只能用來作科學計算或者是工程計算。

NumberFormat類的format()方法可使用BigDecimal對象做爲其參數,能夠利用BigDecimal對超出16位有效數字的貨幣值,百分值,以及通常數值進行格式化控制。 

驗證:

double a = 1.0-0.9;//0.09999999999999998
double b=1,c=1.0;
System.out.println(b==c);//true
double d=0.09999999999999998;//0.09999999999999998
double e=1/10;
System.out.println("e="+e);//0.0
//float f=0.09999999999999998;不兼容,失精度
float g=0.09999999999999998f;//0.1
System.out.println(new BigDecimal(0.1));//0.1000000000000000055511151231257827021181583404541015625
System.out.println(new BigDecimal("1").subtract(new BigDecimal("0.9")));//0.1
相關文章
相關標籤/搜索