我用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 !!!
我不明白!请帮忙! : - )
答案 0 :(得分:3)
这将归因于浮点计算。
您的计算
g * 100
已经带回来了
229.99999999999997
问题出在哪里。
查看INFO: Precision and Accuracy in Floating-Point Calculations
另请查看Floating point
准确性问题
浮点数的事实 不能准确地代表所有真实的 数字和那个浮点数 操作无法准确表示 真正的算术运算,导致 许多令人惊讶的情况。这是 与有限精度有关 哪些计算机通常代表 号。
答案 1 :(得分:2)
正如其他人已经提到的,这是由于计算机中浮点数的精度有限。这些不精确现象出现在任何地方都有关于浮点数的艰难是/否决定。为了解决问题,您可以添加/减去一个小数字,以找到正确的答案,直到达到一定的准确度。
您可能会发现这些功能很有用:
#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的值不。例如,将两个数字a
和b
进行比较可以通过两种方式进行比较:isEqualAcc(a, b)
和isEqualAcc(a-b, 0)
。您可能希望从两种方式获得相同的结果,即使在第二种方式中,数字x可能要小得多。
答案 2 :(得分:0)
这是一种使用中间整数结果的可能方法:
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