簡體   English   中英

與Objective-C中的地板問題一起回合

[英]Round with floor problem in Objective-C

我用e和s計算g,這些都是雙打。 之后我想在第二個之后切斷所有數字並將結果保存在x中,例如:

g = 2.123 => x = 2.12

g = 5.34995 => x = 5.34

等等。 我用...

g = 0.5*e + 0.5*s;
x = floor(g*100)/100;

......而且大部分時間都可以正常工作。 但有時我會得到奇怪的結果。 例如:

e = 3.0 s = 1.6 g = 2.30但x = 2.29 !!!

所以我試圖追查錯誤:

g = 0.5*e + 0.5*s;
NSLog(@"%f",g);

給我g = 2.30

g = g * 100;
NSLog(@"%f",g);

給我g = 230.0

x = floor(g);
NSLog(@"%f",x);

結果x = 229.0 !!!

我不明白! 請幫忙! :-)

這將歸因於浮點計算。

你的計算

g * 100

已經帶回來了

229.99999999999997

您的問題源自何處。

看一下INFO:浮點計算的精度和准確度

另請看浮點

准確性問題

事實上,浮點數不能精確地表示所有實數,並且浮點運算不能精確地表示真正的算術運算,這會導致許多令人驚訝的情況。 這與計算機通常表示數字的有限精度有關。

正如其他人已經提到的那樣,這是由於計算機中浮點數的精度有限。 這些不精確現象出現在任何地方都有關於浮點數的艱難是/否決定。 為了解決問題,您可以添加/減去一個小數字,以找到一個正確的答案,達到一定的准確度。

您可能會發現這些功能很有用:

#define ACC 1e-7

double floorAcc( double x ) { return floor(x + ACC);}
double ceilAcc( double x ) { return ceil(x - ACC); }
bool isLessThanAcc( double x, double y ) { return (x + ACC) < y; }
bool isEqualAcc( double x, double y ) { return (x + ACC) > y && (x - ACC) < y; }

當然,這些只能在有限的范圍內工作。 使用非常小或非常大的數字時,您需要為ACC選擇另一個值。

請注意,'ACC'的值通常取決於應用程序中數字的准確性, 而不取決於x的值。 例如,比較兩個數字ab的相等性可以用兩種方式完成: isEqualAcc(a, b)isEqualAcc(ab, 0) 您可能希望從兩種方式獲得相同的結果,即使在第二種方式中,數字x可能要小得多。

以下是使用中間整數結果的可能方法:

double e = 3.0;
double s = 1.6;

NSInteger e1 = e * .5 * 100.0; // 150
NSInteger s1 = s * .5 * 100.0; // 80

double x = (e1 + s1)/100.0; // 2.3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM