繁体   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