与Mac和Linux上的exp函数略有不同的结果 [英] Slightly different result from exp function on Mac and Linux

查看:57
本文介绍了与Mac和Linux上的exp函数略有不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下C程序在Mac和Linux上产生不同的结果.我很惊讶,因为我认为 libm 的实现已经标准化了

The following C program produces different results on my Mac and on Linux. I'm suprised because I assumed that the implementation of libm is somehow standardized

#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

这两个编译器都没有任何优化标志,如下所示:

Both were compiled without any optimization flags as follows:

gcc -lm ....

我知道我绝对不应该将浮点数完全相同.

I know that I never should compare floats to be excatly the same.

这个问题是在调试期间出现的,遗憾的是使用此计算证明的算法在数值上是不稳定的,并且这种微小的差异导致最终结果出现重大偏差.但这是一个不同的问题.

This issue came up during debugging, regrettably the algorithm using this calculation proofs to be numerically unstable and this slight difference leads to significant deviations in the final result. But this is a different problem.

令我惊讶的是,诸如 exp 之类的基本运算未标准化,正如我对IEEE 754规定的基本代数运算所期望的那样.

I'm just surprised that such basic operations as exp are not standardized as I can expect for the basic algebraic operations specified by IEEE 754.

对于不同的机器或不同的版本,对于 libm 的不同实现,是否可以依靠任何精度的假设?

Are there any assumptions about precision I can rely on for different implementations of libm for different machines or for different versions ?

由于下面的讨论,我使用了 mpmath 来计算比机器精度更高的值,并且我又得到了两个数字,结果是 9.2071868113398768244 结果最后一个数字已经是错误的.linux下的结果可以通过对此值进行四舍五入来解释,如果计算机使用四舍五入,则Mac结果也将关闭.

Because of the discussion below I used mpmath to compute the value with higher than machine precision and I get with two more figures the result 9.2071868113398768244, so for both of my results the last figure is already wrong. The result on linux can be explained by down rounding this value, the Mac result is also off if the computer uses up rounding.

推荐答案

C99规范指出(其他版本应相似)

The C99 Specification states (other version should be similar):

J.3实现定义的行为

1符合标准的实现是需要记录其在每个领域中的行为选择在本节中列出.以下是实现定义的内容:

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浮点数

-浮点运算的精度和< math.h> < complex.h> 中的库函数返回浮点结果(5.2.4.2.2).

— 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.

Meaning GNU libm and BSD libm are free to have different levels of accuracy. Likely what is happening, is that the BSD implemention on OSX rounds to the nearest (unit in the last place) ULP, and the GNU implementation truncates down to the next ULP.

这篇关于与Mac和Linux上的exp函数略有不同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆