浮點數精度計算出現的問題

2021-09-06 23:40:49 字數 1788 閱讀 1305

當我們儲存浮點數後再讀取浮點數,結果可能會出現一點點偏差。

比如:float ft1 = 20.2;(這樣編譯器會報警告,因為小點數預設為double)

cstring str;

str.format(_t("%f"),ft1);

這時候ft1的值等於20.200001。

float ft2 = 20.8;

cstring str;

str.format(_t("%f"),ft2);

這時候ft1的值等於20.799999。

解決方法1:

將float改用double儲存:

double dt1 = 20.2;

解決方法2:

使用%g格式化,除去0後的有效位數。

float ft1 = 20.2;

cstring str;

str.format(_t("%g"),ft1);

這時候ft1的值等於20.2。但是沒法再用0對齊了,嘿嘿嘿嘿。。。。。。

解決方法3:

使用%0.4格式化

float ft1 = 20.2;

cstring str;

str.format(_t("%0.4f"),ft1);

這時候ft1的值等於20.2000。

還有些比較複雜的,比如說計算過程中出現了精度損失。

我們通過簡單的**試驗一下:

int newwidth, newheight;

getthumbnailsize(200, 200, 100, 100, out newwidth, out newheight);

console.writeline(", ", newwidth, newheight);

getthumbnailsize(300, 300, 100, 100, out newwidth, out newheight);

console.writeline(", ", newwidth, newheight);

得到的結果是:

100, 100

99, 100

第乙個結果自然沒有問題,但是在第二個結果中為什麼是99而不是100?為此,我們再通過以下的**來觀察一番:

ratio: 0.3333333333333333333333333333

new value: 99.99999999999999999999999999

to int: 99

可見,雖然使用了decimal,精度已經非常高的,但是在經過了一除一乘,它還是沒有恢復到最精確值。雖然一直說要注意浮點數計算時的精度問題,但是對於這個問題許多朋友往往只是理解到「不能直接兩個浮點數相等」,包括我自己的第一印象。但事實上,從上面的結果也可以看出,把乙個浮點數直接轉換成整形,它便是使用了「去尾」而不是「四捨五入」的方法。因此,雖然newvalue的值無比接近100,但是在強制去尾後它還是變成了99。

如果要在原來的方法中改變這個問題,最簡單的方法可能是把最後的強制轉型替換成math.round方法。math.round方法使用四捨五入,應該能夠解決問題。不過如果只是這樣的話收穫不大,我們再仔細想想,應該如何做到盡可能的精確。

兩個浮點數相除可能會喪失精度,但如果是乘法操作,在一般情況下精度是不會丟失的,除非發生了溢位的話,或者小數字數太多。因此在計算過程中為了保持精度,我們應該盡可能的做乘法,而不是作除法。例如以下的判斷:

if ((decimal)desiredwidth / originalwidth < (decimal)desiredheight / originalheight)
其實最好改寫成「等價」的乘法操作。

浮點數精度問題

一 例子 首先我們去編譯器試試 double a 1.9 通過新增監視檢視a的值 會發現a的值是1.8999999 二 開始今天的學習 在最開始學c 的時候並沒有對浮點數進行很深入的學習,認為浮點不就是小數嘛,首先在c 的巨集裡面有 flt max 和 flt min 的定義,float是四位元組的...

浮點數的精度問題

float 1bit 符號位 8bits 指數字 23bits 尾數字 double 1bit 符號位 11bits 指數字 52bits 尾數字 對於二進位制的小數 1.1 1 20 1 2 1 1 1 2 1.5 1.01 1 20 0 2 1 1 2 2 1 1 4 1.25 1.0011 1...

浮點數精度丟失問題

c 中的浮點數,分單精度 float 和雙精度 double float 是 system.single 的別名,介於 3.402823e38 和 3.402823e38 之間的32位數字,符合二進位制浮點演算法的 iec 60559 1989 ieee 754 標準 double 是 system...