節選自 :
浮點數(以c/c++為準),一般用的較多的是float, double。
佔位元組數
數值範圍
十進位制精度位數
float 4
-3.4e-38~3.4e38
6~7double 8
-1.7e-308~1.7e308
14~15
如果記憶體不是很緊張或者精度要求不是很低,一般選用double。14位的精度(是有效數字位,不是小數點後的位數)通常夠用了。注意,問題來了,資料精度位數達到了14位,但有些浮點運算的結果精度並達不到這麼高,可能準確的結果只有10~12位左右。那低幾位呢?自然就是不可預料的數字了。這給我們帶來這樣的問題:即使是理論上相同的值,由於是經過不同的運算過程得到的,他們在低幾位有可能(一般來說都是)是不同的。這種現象看似沒太大的影響,
卻會一種運算產生致命的影響: ==
。恩,就是判斷相等。注意,
c/c++
中浮點數的
==需要完全一樣才能返回
true
。
#include#includeint main()
輸出:
a = 3.14159265358979360000
b = 3.14159265358979310000
a - b = 0.00000000000000044409
a == b = 0
我們解決的辦法是引進eps,來輔助判斷浮點數的相等。
eps縮寫自
epsilon
,表示乙個小量,但這個小量又要確保遠大於浮點運算結果的不確定量。
eps最常見的取值是
1e-8
左右。用法如下:
#includevoid main()
printf("e=%lf\n",e);
}long fun(int n)//求n!的函式
則各種判斷大小的運算都應做如下修正:
傳統意義
修正寫法
a == b
fabs(a – b) < eps
a != b
fabs(a – b) > eps
a < b
a – b < -eps
a <= b
a – b < eps
a > b
a – b > eps
a >= b
a – b > -eps
這樣,我們才能把相差非常近的浮點數判為相等;同時把確實相差較大(差值大於eps)的數判為不相等。
ps: 養成好習慣,盡量不要再對浮點數做==判斷。例如,我的修正寫法裡就沒有出現==。
eps帶來的函式越界
如果sqrt(a), asin(a), acos(a) 中的a是你自己算出來並傳進來的,那就得小心了。
如果a本來應該是0的,由於浮點誤差,可能實際是乙個絕對值很小的負數(比如1e-12),這樣sqrt(a)應得0的,直接因a不在定義域而出錯。
類似地,如果a本來應該是±1,則asin(a)、acos(a)也有可能出錯。
因此,對於此種函式,必需事先對a進行校正。
浮點數比較大小
在數 算當中經常會涉及到判斷兩個數是否相等的情況 對於整數很好處理 a b這樣的乙個語句就可以 解決全部的問題 但是對於浮點數是不同的 首先,浮點數在計算機當中的二進位制表達方式就決定了大多數浮點數都是無法精確的表達的 現在的計算機大部分都是 數字計算機,不是模擬機,數字機的離散化的資料表示方法自然...
浮點數比較大小
浮點數比較大小,由於精度問題,所以直接比較有時可能會出錯。單精度數7位有效數字。float 雙精度數16位有效數字。double 單精度數的尾數用23位儲存,加上預設的小數點前的1位1,2 23 1 16777216。因為 10 7 16777216 10 8,所以說單精度浮點數的有效位數是7位。雙...
PHP浮點數比較大小
php 比較運算子用於比較兩個值 數字或字串 等於 x y 如果 x 等於 y,則返回 true。全等 完全相同 x y 如果 x 等於 y,且它們型別相同,則返回 true。a 0.58 100 b 58 var dump a 輸出 float 58 var dump b 輸出 int 58 va...