關於浮點數的一些問題

在stackoverflow中看到的,以前用float類型數據比較少,因此沒怎麼研究。現在看看
看看測試代碼linux

int main()
{
    float a = 0.7;
    float b = 0.5;
    if (a < 0.7)
    {
       if (b < 0.5) printf("2 are right");
       else         printf("1 is right");
    }
    else printf("0 are right");
}

依照理論狀況應該是第一個if不進入,在linux 64位上看看
這裏寫圖片描寫敘述
這個狀況發生了,
另外一個代碼
這裏寫圖片描寫敘述
執行結果是
這裏寫圖片描寫敘述
就上面兩種狀況分析一下。markdown

先看看這兩種寫法
0.7和.7
一個小代碼實驗post

#include<stdio.h>

int main()
{
 float a=0.7;
 printf("%zu\n",sizeof(a));
 printf("%zu\n",sizeof(0.7));
 printf("%zu\n",sizeof(.7));

 return 0;
}

執行結果是
這裏寫圖片描寫敘述
是否是可以這樣以爲。對於常值小數。os是將其默認設置爲double 型的。ui

上面都是一些實驗現象。爲了更深刻理解浮點數。看看浮點數在計算機中是怎麼存儲和計算的。編碼

咱們知道 對於十進制而言。
大於0的權重是10正次冪,而小於零的是10負次冪,因此
對於二進制小數,相同採樣這個方案,
因此這裏面就會出現一個問題。對於有限長度的編碼。十進制是不能表示分數的。而對於二進制小數僅僅能表示能被二整除的一些數,並不能準確的表示。僅僅能近似的表示。spa

僅僅有添加二進制編碼長度纔會將這個偏差縮小,code

IEEE是怎樣將浮點數存儲起來的,
這裏寫圖片描寫敘述
爲了說明這個問題 ,採用union來查看float的存儲數據htm

union f
{
 int p;
 float f;
};

int main()
{
     union f  tf;
     tf.f=0.1;
     printf("%x\n",tf.p);
     return 0;
}

這裏寫圖片描寫敘述
0_01111011_10011001100110011001101圖片

因此現在已經明確一個事實就是。從正數小數到二進制小數之間的轉化實際上並不是全然相等的轉化,是有必定偏差的。對於同一個十進制小數轉化成float和double由於編碼位數的不一致,結果也是不一樣的。get

爲此在比較浮點數時,採用的是偏差比較法
if (fabs(result - expectedResult) < 0.00001)
fabs用於計算小數之間的絕對值的

result和expectedResult是兩個需要比較的浮點數

stackoverflow的問題原地址
http://stackoverflow.com/questions/7011184/floating-point-comparison

如下是一個國外人寫的關於浮點數的文章
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

相關文章
相關標籤/搜索