数学的功能功能在几个环境中返回多个结果
我正在开发C ++的程序。我必须使用数学库的 POW
执行一些计算。
当运行此代码时:
#include <math.h>
#include <stdio.h>
int main (void)
{
unsigned long l;
double d1,d2,d3;
l = 13831305406817642647;
d1 = 2.;
d2 = *((double*)(&l));
d3 = pow(2.,d2);
printf ("%lu,%20.20f\n",*((unsigned long *)(&d1)),d1);
printf ("%lu,%20.20f\n",*((unsigned long *)(&d2)),d2);
printf ("%lu,%20.20f\n",*((unsigned long *)(&d3)),d3);
return 0;
}
使用Fedora 35,我将获得:
4611686018427387904,2.00000000000000000000
13831305406817642647,-1.16674465427289475450
4601695688420081959,0.44542528011426657519
但是使用Fedora 36:
4611686018427387904,2.00000000000000000000
13831305406817642647,-1.16674465427289475450
4601695688420081958,0.44542528011426651968
我将双打转换为无符号的二进制图像,长时间检测任何更改。
在第三行中,您可以观察到这种变化。 当我用POW计算相同的值时,为什么会获得不同的结果?
有关Fedora版本的完整信息(使用 UNAME -R
获得):
对于Fedora 35:5.17.11-200.fc35.x86_64
for Fedora 36:5.17.0-0-0.rc7.116。 FC36.x86_64
欢迎任何帮助。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我使用 X86-64 GCC 12.1 在编译器资源管理器中两次编译您的代码:。唯一的区别是优化水平,这导致输出有所不同。
在测试中,
-O1
启用编译器在编译过程中计算d3
并通过460169568420081958
直接到printf(printf(printf)
。有趣的是, x86-64 clang 能够用
-O1
来计算d3
,结果为4601695688420081959
(与POW(2.,D2)
相同。基本上,如果优化级别不是
-O0
,则编译器将删除pow()
的使用,并且可行的恒定计算是可行的。我猜 gcc 使用自己的方法来计算pow()
,而 clang call 调用pow> pow()
或使用获得答案的类似方法。您可以使用objdump
从可执行文件中获取汇编代码以检查详细信息。I used x86-64 gcc 12.1 to compile your code twice in Compiler Explorer: https://godbolt.org/z/47K94dMe3. The only difference was the optimization level, which caused the outputs to differ.
In the test,
-O1
enabled the compiler to calculate thed3
during compilation and pass4601695688420081958
directly toprintf()
.Interestingly, x86-64 clang is able to compute
d3
with-O1
, and the result is4601695688420081959
(the same aspow(2.,d2)
).Basically, compilers will remove the use of
pow()
if optimization level is not-O0
, and a constant calculation is viable. I guess gcc uses its own method to computepow()
, while clang callspow()
or uses a similar approach to get the answer. You can useobjdump
to get assembly code from your executables to check the details.