文章來源:csdn 作者:treeroot
浮點數分為單精確度和雙精確度,Java中的單精確度和雙精確度分別為float和double.你們知道float和double是怎麼儲存的嗎?
float佔4個位元組,double佔8個位元組,為了方便起見,這裡就只討論float類型.
float其實和一個int型的大小是一樣的,一共32位,第一位表示符號,2-9表示指數,後面23位表示小數部分.這裡不多說,請參考:http://blog.csdn.net/treeroot/archive/2004/09/05/95071.aspx
這裡只舉一個例子,希望能拋磚引玉,就是研究一下浮點數0.1的儲存形式,先運行這個程式.
|
public class Test{ public static void main(String[] args) { int x = 0x3d800000; int i = 1 << 22; int j = 1 << 4; float f = 0.1f; int y = Float.floatToIntBits(f); float rest = f - ( (float) 1) / j; while (i > 0) { j <<= 1; float deta = ( (float) 1) / j; if (rest >= deta) { rest -= deta; x |= i; } i >>= 1; } pr(x); pr(y); } static void pr(int i) { System.out.println(Integer.toBinaryString(i)); } } |
結果:
111101110011001100110011001101
111101110011001100110011001101
程式說明:
int x=0x3d80000;
因為浮點表示形式為1.f*2n-127我們要表示0.1,可以知道n-127=-4,到n=123
符號為正,可知前9是 001111011,暫時不考慮後面的23位小數,所以我們先假設x=0x3d800000;
i初始為第右起第23位為1,就是x的第10位
i初始為4,因為n-127為-4,這裡是為了求它的倒數.
|
float f = 0.1f; int y = Float.floatToIntBits(f); |
y就是它的32位表示
|
float rest = f - ( (float) 1) / j; |
這個rest表示除了1.f中的1剩下的,也就是0.f
|
while (i > 0) { j <<= 1; float deta = ( (float) 1) / j; if (rest >= deta) { rest -= deta; x |= i; } i >>= 1; } |
這個迴圈來計算23位小數部分,如果rest不小於deta,表示這個位可以置為1.
其他的不多說了,輸入結果是一樣的,可以說0.1這個浮點數肯定是不精確的,但是0.5可以精確的表示,想想為什麼吧