計算機存儲小數偏差
❶ 為什麼用%g存儲的小數有變化
這涉及到兩個方面的問題:
①電腦對浮點數(float)的表述。32位對浮點數的表達是:0~22位=尾數;23~30是指數,31位則是符合位。說白了就是十進制的小數部分是按照1/2+1/4+1/8+....這樣的方式去逼近的,因此存在誤差,也就是所謂的{存儲精度}的問題。上面的121.6234其實電腦中的16進制數是:0x42f33f2e,再轉換回10進制≈121.62339782714844,不同的編譯器在不同的機器上,還有些許的誤差。因此雖然文件中是121.6234,但讀取到電腦內存中時按二進制或16進制存儲,在printf時,按格式又轉換,因此二者之間存在轉換誤差。
②%f和%g的區別。不帶控制長度的%f,只表示6位精度(即小數點後面),因此%f≈121.623398,而%g則是{最多}6位(有效位含小數點前後),因此%g≈121.623。
而%.9g則表示最多有效位9位,這個處理是在0x42f33f2e(121.62339782714844)這個數基礎上作的取捨,≈121.623398(...78四捨五入)。
也正是這個原因,高精度浮點運算有專門的庫。
③ 可以用double替代float提高精度。因為在電腦中,double是64位,尾數部分有52位表示,11位指數位和1個符號位構成。121.6234 = 1.216233978271484375E2 = 0x405E67E5C91D14E4,因此更逼近121.6234. 演示代碼如下:
#include<stdio.h>
intmain(intargc,charconst*argv[])
{
floata=121.6234;
doubled=121.6234;
printf("%.9g%f ",a,a);
printf("%.9g%f ",d,d);
return0;
}
運行:
121.623398121.623398
121.6234121.623400
❷ excel計算數據不一致怎麼辦
換一台電腦試試吧,應該是浮點小數產生的誤差,可能換一台電腦就可以了。
以下是摘自excelhome論壇,來自灰袍法師的一篇詳細介紹:
很多人在日常使用Excel,可能都沒有注意到浮點小數帶來的計算誤差問題
因為日常使用的運算結果,肯定都是四捨五入之後的結果,可以排除浮點誤差的影響
但是,浮點小數的誤差,也會出現在運算的過程,有可能導致最終結果出錯。
比方說 countif(A1:A10000,"=B1")這樣的簡單統計,也有可能出錯。
附件生成5萬個隨機小數(四捨五入到2位小數位),加上然後馬上減去同一個整數
對比計算前後的數值是否相等(數學上當然是絕對相等的,但是電腦的運算結果就不一定了。。。。。。)
附件會自動找出一批在你的電腦上會出現浮點小數誤差導致錯誤的運算。
出現浮點小數運算誤差的原因很簡單,小數有無窮多個
甚至一個小數也有無窮多位,如十進制的1/3,或者二進制的0.1
所以計算機存儲小數的時候,必定只能存儲所有小數的一部分,而無窮小數則必須截斷
因此,一個小數有時候就只能取一個接近值而不是精確值
而對應的浮點數運算,也只能得到接近值,而不是精確值
不同的CPU,比方說Intel的跟AMD的,或者奔騰跟賽揚,在硬體上對於截斷的位置是不一樣的
所以,同一個運算在不同的機器就可能有不同的結果
這也是為什麼論壇經常有人說xx運算不正確,然後回帖的人說我的機器沒事,其實就是CPU不同而已
另一方面,不同的軟體,內部計算的時候,也許用了不同的CPU硬體實現的數據類型,或者精度設置也不一樣,
所以,同一個運算在不同的軟體也可能有不同的結果
編程,寫公式要注意,假設 x,y 都是浮點數,er。。。。。。excel的每個小數單元格都是浮點數
那麼永遠不要寫 if x=y 這樣的句子,因為很可能數學上相等的x和y,在計算機內部是不等的
應該寫成 if |x-y| / max(|x|,|y|) <= 0.0000000000001 之類
或者簡單一點,用if round(x) = round(y) 來判斷,這樣最末一位的尾數浮點存儲誤差就不會影響整個數值了。
幸運的是,整數和定點小數不會受影響,編程時應該優先考慮使用整數和定點小數類型
另一方面,即使浮點小數可以完全表示我們要計算的數值,但是計算結果卻也有可能產生誤差
浮點,定點的意思是指小數點的位置
定點小數:小數點位置固定。
以十進制為例,假設一個數值類型可以有6個十進制位置,那麼定點類型無須記錄小數點位置,可以有以下類型:
整數類型,小數點位置就一定是個位後面,能夠表達的最精確數字就是1,能夠表達的范圍是 000000 - 999999
兩位小數類型,小數點位置就一定是百分位,能夠表達的最精確數字就是0.01,,能夠表達的范圍是 0000.00 - 9999.99
。。。。。。等等
浮點小數:小數點位置可以變動,並且需要額外的記錄去描述這個變動的小數點位置。
假設這里把其中一個位置用於記錄小數點位置(可變范圍 0-9),並且規定:
小數點位置取5,表示精度是1,小數點在個位後面,這個數值類型有0個小數位,可以表示 00000 到 99999 的數 (注意:這里只有5位有效數字)
小數點位置取6,表示精度是 0.1,小數點在十分位後面,這個數值類型有1個小數位,可以表示 0000.0 到 9999.9 的數
小數點位置取9,表示精度是 0.0001,小數點在萬分位後面,這個數值類型有4個小數位,可以表示 0.0000 到 9.9999 的數
......
小數點位置取4,表示精度是 10,表示小數點在十位,這個數值類型可以表示 00000 x 10 到 999990 的數,精度是 10
......
小數點位置取0,表示精度是 100000,表示小數點在十萬位,這個數值類型可以表示 00000 x 100000 到 9999900000 的數,精度是 100000
可見浮點小數通過可變的小數位置,使一個數值類型可以用一部分表示有效數字,另一部分表述每一單位有效數字的倍率
從而靈活地表示很大范圍的數值,代價是:由於用了一部分記錄內容去記錄小數點位置,所以有效數字的長度比定點小數要低。
而且,一些定點數運算不會出現的問題,在浮點數運算會出現
如兩個數相加
如果第一個浮點數是 100.01,第二個浮點數是 9999900000
按上述規則,這兩個都是合法的浮點數,可是它們的和 99999000100.01 卻無法用同一個浮點數類型表示出來。
一般計算機碰到這種情況,就會自動按比較大的數值來四捨五入,於是
100.01 + 9999900000 = 9999900000 (出現了100.01的誤差)
這也是浮點數誤差產生的一個原因:小的數值被大的數值「吸收」了。
要在Excel證明這一點就太簡單了,因為excel的double類型浮點小數只有15個有效數字(即最多記錄15個十進制數字)
所以Excel的單元格運算 12345012345678900000 + 12345.0123456789 = 12345012345678900000
更多的浮點小數知識,可以搜索論壇或者網路。
http://support.microsoft.com/kb/78113
❸ excel表 小數點只有兩位的數據求和,出現誤差怎麼解決
原因:在Excel進行計算時在計算機中是轉換成二進制進算然後保留數值的,所以會出現誤差。
解決方法:
1、打開excel表格,在單元格A1中輸入數字「2.88」,在單元格B1中輸入數字「5.89」。
❹ 在excel裡面運算,小數點後面的數字有時候有微小偏差,怎麼回事
計算機運算用二進制,在和十進制轉換的時候產生的浮點運算偏差,在外面套個round函數即可,假如你的運算精度是小數點後2位,那麼在外面套個round(原來公式,3)即可
❺ C語言中實數計算和存儲為什麼有微小的誤差
計算機中表示浮點數是採用近似值的~
這個問題可以說是計算機用有限的位來表示無限的數,因為位數有限計算機中儲存的數自然不可能是連續的,應該是離散的值。當某個值它不能精確的表示時,它就要決定用它附近的值了。
假設有一台這樣的機器,它能表示1.0 1.2 1.4 1.8(只能精確到小數後一位),如果我要用到1.25呢,它可能就會用1.2來代替了。當然位數越多,表示的值就越精確,所以double 會比float 精確。
❻ 計算機實數存儲誤差
這是因為計算機保存浮點數時,
是把數看作a*(2^b)這樣的形式的,而不是我們直觀上認為的以10為底數,
在計算機內部處理時是以2為底數的。
即將數轉換成以2為底的「科學計數法」的形式,
再由這個形式反轉換成10進制形式,
但是由於數據有位數的限制,
所以有些數轉換成二進制計數形式後位數超出了限制的位數,那麼超出的位就被截去了,
那麼轉換回來時得到的數就會與原數有偏差,不同的數這個偏差是不同的,
有可能在小數點後第7位,也有可能在第8位,也有可能在其他位數,
但是能保證第6位之前是正確的。