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 */