4

以下C代码

int main(){
    int n=10;    
    int t1=pow(10,2);
    int t2=pow(n,2);
    int t3=2*pow(n,2);
    printf("%d\n",t1);
    printf("%d\n",t2);
    printf("%d\n",t3);
    return (0);
}

给出以下输出

100
99
199

我正在使用 devcpp 编译器。这没有任何意义,对吧?有任何想法吗?(那个 pow(10,2) 可能类似于 99.9999 并不能解释第一个输出。此外,即使我包含 math.h,我也得到了相同的输出)

4

3 回答 3

6

您正在使用质量差的数学库。一个好的数学库会返回可精确表示的值的精确结果。

通常,数学库例程必须是近似值,因为浮点格式不能准确表示精确的数学结果,而且计算各种函数很困难。但是,对于pow,可以精确表示的结果数量有限,例如 10 2。一个好的数学库将确保正确返回这些结果。您正在使用的库无法做到这一点。

于 2013-06-04T16:55:59.870 回答
3

将结果计算存储为doubles。打印为double,使用%f而不是%d。你会看到99真的更像99.999997,这应该更有意义。

一般来说,在处理任何浮点数学时,您应该假设结果是近似的;也就是说,在任何一个方向上都有点偏离。所以当你想要准确的结果时——就像你在这里所做的那样——你会遇到麻烦。

在使用函数之前,您应该始终了解函数的返回类型。参见,例如cplusplus.com

double pow (double base, double exponent); /* C90 */

从其他答案中,我了解到在某些情况下您可以期望pow或其他浮点数学是精确的。一旦您了解了困扰浮点数学的必要不精确性,请查阅这些。

于 2013-06-04T17:00:44.310 回答
2

您的 variables t1t2并且t3必须是类型double,因为pow()返回双精度。


但是,如果您确实希望它们是 typeint,请使用round()function。

int t1 = pow(10,2);
int t2 = round(pow(n,2));
int t3 = 2 * round(pow(n,2));

它将返回的值四舍五入到99.9...和。然后因为它是类型的,所以也是。199.9...100.0200.0t2 == 100intt3

输出将是:

100
100
200

因为round无论当前的舍入方向如何,该函数返回最接近 x 舍入的整数值中途情况远离零。


更新:这是来自的评论math.h

/* Excess precision when using a 64-bit mantissa for FPU math ops can
cause unexpected results with some of the MSVCRT math functions.  For
example, unless the function return value is stored (truncating to
53-bit mantissa), calls to pow with both x and y as integral values
sometimes produce a non-integral result. ... */
于 2013-06-04T16:49:53.193 回答