C 在我的编译器和操作系统中,当n=5时,为什么pow(n,2)返回24? #包括 #包括 #包括 int main() { int n,i,ele; n=5; ele=pow(n,2); printf(“%d”,ele); 返回0; }

C 在我的编译器和操作系统中,当n=5时,为什么pow(n,2)返回24? #包括 #包括 #包括 int main() { int n,i,ele; n=5; ele=pow(n,2); printf(“%d”,ele); 返回0; },c,math.h,c-standard-library,C,Math.h,C Standard Library,输出为24 我在代码::块中使用GNU/GCC 发生了什么事 我知道pow函数返回一个double,但是25适合一个int类型,那么为什么这个代码打印一个24而不是25?如果n=4;n=6;n=3;n=2代码可以工作,但五个参数不能工作。如果不包含则编译器不知道pow()的参数类型,这两个参数都是double而不是int,因此会得到一个未定义的结果。你得到24,我得到16418。当你把pow和变量一起使用时,它的结果是double。分配给int会截断它 因此,您可以通过将pow的结果分配给dou

输出为
24

我在代码::块中使用GNU/GCC

发生了什么事


我知道
pow
函数返回一个
double
,但是
25
适合一个int类型,那么为什么这个代码打印一个
24
而不是
25
?如果
n=4;n=6;n=3;n=2
代码可以工作,但五个参数不能工作。

如果不包含
则编译器不知道
pow()
的参数类型,这两个参数都是
double
而不是
int
,因此会得到一个未定义的结果。你得到24,我得到16418。

当你把pow和变量一起使用时,它的结果是
double
。分配给
int
会截断它

因此,您可以通过将
pow
的结果分配给
double
float
变量来避免此错误

所以基本上


它转换为
exp(log(x)*y)
,这将产生一个与
x^y
不完全相同的结果-只是一个近似的浮点值,。因此,例如
5^2
将变成
24.999996
25.00002

以下是可能发生的情况。您应该能够通过查看编译器对
pow
函数的实现来确认这一点:

假设您拥有正确的#include(之前所有关于此的答案和评论都是正确的——不要想当然地认为
#include
文件),标准
pow
函数的原型如下:

双倍功率(双倍,双倍)

你打电话给pow的方式如下:

pow(5,2)

pow
函数经过一个算法(可能使用对数),因此使用浮点函数和值来计算幂值

pow
函数不会经历简单的“将x的值乘以n次”,因为它还必须使用分数指数来计算
pow
,而您不能这样计算分数幂

因此,更可能的是,使用参数5和2计算
pow
会产生轻微的舍入误差。当分配给
int
时,截断了小数,从而得到24

如果您使用的是整数,那么您也可以编写自己的“intpow”或类似函数,只需将值乘以所需的次数。这样做的好处是:

  • 使用
    pow
    ,您不会遇到细微的舍入错误

  • 您的
    intpow
    函数很可能比对
    pow
    的等效调用运行得更快


  • 您希望从用于双精度运算的函数中得到int结果

    你也许应该使用

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int main()
    {
        int n,i,ele;
        n=5;
        ele=pow(n,2);
        printf("%d",ele);
        return 0;
    }
    

    虽然可以精确地加和减小值,但是
    pow()
    函数通常通过对数相乘来工作,因此即使输入都是精确的,结果也不是精确的。分配给
    int
    总是截断,因此如果不精确性为负,则得到24而不是25

    这个故事的寓意是对整数使用整数运算,当实际参数要提升或截断时,要怀疑
    函数。不幸的是,除非您添加
    -Wfloat conversion
    ,否则GCC不会发出警告(它不在
    -Wall-Wextra
    中,可能是因为在许多情况下,这种转换是预期的和需要的)


    对于整数幂,使用乘法(如果是负数,则使用除法)比使用
    pow()
    更安全、更快-将后者保留在需要的地方!不过,一定要注意溢出的风险。

    您可以尝试在
    float
    double
    变量中获取
    pow
    的返回值,然后尝试将其键入
    int
    。看看这是否也会产生
    24
    或正确答案
    25
    @exsnake-
    pow
    函数不仅仅是5*5的乘法。最终结果可能是
    24.9999999
    或类似结果。
    pow
    函数可能使用对数来计算结果,因为它还必须处理分数幂。要确认这一点,请查看编译器对
    pow
    的实现。您应该澄清您正在使用的操作系统,因为这几乎肯定是标准库数学部分实现中的一个错误。我猜你正在Windows上使用mingw和MSVCRT…你能分享
    printf(“%.25lf\n”,pow(n,2))的输出吗
    在您的实现上,其中
    n=5
    ?良好的
    pow(n,2)
    将返回完全正确的结果。C没有指定pow()必须有多好。我在一次测试中问了助教,助教告诉我在测试中使用int-instant和double,他说是的,使用int。但现在我可以看出他错了。你的助教需要意识到,你不应该调用用于
    类型的函数,并假设它将使用基于
    整数的实现。最好使用
    ele=round(0.5+pow(n,2))。虽然在这种情况下,
    pow(n,2)
    不应返回小于零的结果,
    y=(int)(0.5+x)
    对于负值
    x
    来说是个问题。不是更好!您应该只使用
    round(pow(n,2))
    。在四舍五入之前添加0.5将有效地四舍五入到下一个整数。如果
    pow(n,2)
    返回25加ε,你会得到26。如果你要滚动你自己的整数幂,你可能应该使用乘法而不是重复乘法,因为后者是O(n),前者是O(logn)。@Aruistante:注意,这个符号表示从线性到logari的转换
    ele=(int)(0.5 + pow(n,2));
    /*    ^    ^              */
    /* casting and rounding   */