数学的功能功能在几个环境中返回多个结果

发布于 2025-02-06 00:35:37 字数 1071 浏览 3 评论 0 原文

我正在开发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

欢迎任何帮助。

I'm developing a program in C++. I have to perform some calculations with pow of math library.
When a run this code:

#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;
}

With Fedora 35 I obtain:

4611686018427387904,2.00000000000000000000
13831305406817642647,-1.16674465427289475450
4601695688420081959,0.44542528011426657519

But with Fedora 36:

4611686018427387904,2.00000000000000000000
13831305406817642647,-1.16674465427289475450
4601695688420081958,0.44542528011426651968

I converted the doubles to a binary image of unsigned long to detect any change for just one bit.

In the third line you can observe this kind of change.
Why I obtain a different result when I calculate over the same values with pow?

The full information about the version of Fedora (obtained with uname -r):

For Fedora 35: 5.17.11-200.fc35.x86_64

For Fedora 36: 5.17.0-0.rc7.116.fc36.x86_64

Any help will be welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雄赳赳气昂昂 2025-02-13 00:35:37

我使用 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 the d3 during compilation and pass 4601695688420081958 directly to printf().

Interestingly, x86-64 clang is able to compute d3 with -O1, and the result is 4601695688420081959 (the same as pow(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 compute pow(), while clang calls pow() or uses a similar approach to get the answer. You can use objdump to get assembly code from your executables to check the details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文