在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