立即警告您这是一项艰巨的任务。
有一个测试。该测试是将一个大问题解析为我们在工作中遇到的一个错误的结果。构造 __ attribute__((noinline))
禁止编译器执行替换函数(用于优化那些没有内爆的东西)。这是保证不会扼杀有趣情况的最简单优化方法。
#include <stdio.h>
double d = 5436277361664796672.000000;
long long ll = 5436277361664796253LL;
int __attribute__((noinline))
func1 (void)
{
double d1 = (double)ll;
if (d > d1)
return 1;
else
return 0;
}
int __attribute__((noinline))
func2 (void)
{
if (d > (double)ll)
return 1;
else
return 0;
}
int
main (void)
{
printf ("%d %d\n", func1(), func2());
return 0;
}
我在 intel
和 sparc
上运行了这个测试。 Gcc
在有优化和无优化的模式下使用。得到如下结果:
sparc: "gcc" printed "0 0"
sparc: "gcc -O2" printed "0 0"
intel: "gcc" printed "0 1"
intel: "gcc -O2" printed "1 1"
差异的原因是什么?无论如何,在分析情况下,如果我自己能够重复一遍,那将是很有用的,但是,当然,几乎没有人有可能在 sparc
上运行这段代码。相反,sparc
可以尝试使用 microsoft 或 borland C 编译器
在 Windows 下运行。我不知道他们会得到什么结果,但无论如何有些东西与任何东西都不匹配(因为我们看到了三个不同的结果)
编辑 1 _attribute_ ((noinline)) - 编译器 gcc 的扩展(忘记写了)。因此VisualStudio无法编译。
最佳答案
我注意到 double 常量的声明有 19 位有效数字,这比 IEEE double (允许 15 到 17 位有效数字)可以表示的更精确。所以 d 不能准确地容纳 5436277361664796672.000000。
两个常量定义字符串在第 16 位变得不同,因此您所在的区域中 double 中的不准确性与这两个数字之间的差异具有相同的幅度。因此,这种比较是不可靠的。
我不知道 C++ 标准是否指定了将过于精确的字符串转换为 double 时会发生什么,但如果确切的结果是未定义的或依赖于实现,我不会感到惊讶。
关于c++ - 将程序从一种体系结构转移到另一种体系结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21866051/