- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
以下 C 程序在我的 Mac 和 Linux 上产生不同的结果。我很惊讶,因为我假设 libm
的实现在某种程度上是标准化的
#include<math.h>
#include<stdio.h>
int main()
{
double x18=-6.899495205106946e+01;
double x19 = exp(-x18);
printf("x19 = %.15e\n", x19);
printf("x19 hex = %llx\n", *((unsigned long long *)(&x19)));
}
Mac 上的输出是
x19 = 9.207186811339878e+29
x19 hex = 46273e0149095886
在 Linux 上
x19 = 9.207186811339876e+29
x19 hex = 46273e0149095885
两者都是在没有任何优化标志的情况下编译的,如下所示:
gcc -lm ....
我知道我永远不应该将 float 比较为完全相同。
这个问题是在debug时出现的,遗憾的是使用这个计算证明的算法在数值上是不稳定的,这种微小的差异导致最终结果有很大的偏差。但这是一个不同的问题。
令我感到惊讶的是,像 exp
这样的基本运算并没有按照我对 IEEE 754 指定的基本代数运算的预期进行标准化。
对于不同机器或不同版本的 libm
的不同实现,我可以依赖任何关于精度的假设吗?
由于下面的讨论,我使用 mpmath
计算了比机器精度更高的值,我用另外两个数字得到了结果 9.2071868113398768244
,所以对于我的两个结果最后一个数字已经错了。 linux 上的结果可以通过向下舍入这个值来解释,如果计算机使用向上舍入,Mac 的结果也是关闭的。
最佳答案
C99规范指出(其他版本应该类似):
J.3 Implementation-defined behavior
1 A conforming implementation is required to document its choice of behavior in each of the areas listed in this subclause. The following are implementation-defined:
...
J.3.6 Floating point
— The accuracy of the floating-point operations and of the library functions in
<math.h>
and<complex.h>
that return floating-point results (5.2.4.2.2).
这意味着 GNU libm 和 BSD libm 可以自由地具有不同的准确性级别。可能发生的情况是,OSX 上的 BSD 实现舍入到最近的(单位在最后一个位置)ULP,而 GNU 实现截断到下一个 ULP。
关于c - exp 函数在 Mac 和 Linux 上的结果略有不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44765611/
直接问题:对于一个类对象的三个(或更多)几乎相同的拷贝,我怎样才能最好(或最有效)地存储它们之间的差异? 背景:我有一个需要一组参数的算法: struct params { std::strin
我是一名优秀的程序员,十分优秀!