Java中的浮點(diǎn)數(shù)分析

字號(hào):

浮點(diǎn)數(shù)分為單精度和雙精度,Java中的單精度和雙精度分別為float和double.你們知道float和double是怎么存儲(chǔ)的嗎?
    float占4個(gè)字節(jié),double占8個(gè)字節(jié),為了方便起見(jiàn),這里就只討論float類(lèi)型.
    float其實(shí)和一個(gè)int型的大小是一樣的,一共32位,第一位表示符號(hào),2-9表示指數(shù),后面23位表示小數(shù)部分.這里不多說(shuō),請(qǐng)參考:《Java中float的取值范圍》。
    這里只舉一個(gè)例子,希望能拋磚引玉,就是研究一下浮點(diǎn)數(shù)0.1的存儲(chǔ)形式,先運(yùn)行這個(gè)程序.
       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));
    }
    }
    結(jié)果:
    111101110011001100110011001101
    111101110011001100110011001101
    程序說(shuō)明:
    int x=0x3d80000;
    因?yàn)楦↑c(diǎn)表示形式為1.f*2n-127我們要表示0.1,可以知道n-127=-4,到n=123
    符號(hào)為正,可知前9是 001111011,暫時(shí)不考慮后面的23位小數(shù),所以我們先假設(shè)x=0x3d800000;
       int i = 1 << 22;
    i初始為第右起第23位為1,就是x的第10位
       int j = 1 << 4;
    i初始為4,因?yàn)閚-127為-4,這里是為了求它的倒數(shù).
       float f = 0.1f;
    int y = Float.floatToIntBits(f);
    y就是它的32位表示
       float rest = f - ( (float) 1) / j;
    這個(gè)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;
    }
    這個(gè)循環(huán)來(lái)計(jì)算23位小數(shù)部分,如果rest不小于deta,表示這個(gè)位可以置為1.
    其他的不多說(shuō)了,輸入結(jié)果是一樣的,可以說(shuō)0.1這個(gè)浮點(diǎn)數(shù)肯定是不精確的,但是0.5可以精確的表示,想想為什么吧.