使用`exp`进行受控舍入是否存在错误?

问题描述 投票:3回答:1

我在某些平台上观察到不正确的(IMO)舍入行为,如下所示:

在取整模式下将log(2)的值计算为FE_DOWNWARDFE_UPWARD(请参阅<fenv.h>)。在我所看到的所有情况下,向下舍入的结果都小于向上舍入的结果,这是我所期望的(结果不准确)。

现在使用相同的舍入模式,对每个结果调用exp。由于exp是单调递增的(在感兴趣区域中的坡度为〜2),所以我希望这些结果会进一步分开。但是在某些经过测试的平台上,exp的两个结果是等效的。

这是一个简单的测试程序:

#include <stdio.h>
#include <math.h>
#include <fenv.h>

int main(void) {
  fesetround(FE_DOWNWARD);
  double xlo = log(2);
  double xxlo = exp(xlo);
  printf("xlo=%.16e xxlo=%.16e\n",xlo,xxlo);

  fesetround(FE_UPWARD);
  double xhi = log(2);
  double xxhi = exp(xhi);
  printf("xhi=%.16e xxhi=%.16e\n",xhi,xxhi); 

  printf("Delta x=%.16e\n",xhi-xlo);
  if (xxlo == xxhi) 
    printf("FAIL\n");
  else 
    printf("Delta xx=%.16e\n",xxhi-xxlo);

  return 0;
}

至强E5520 @ 2.27GHz上的一个(良好)结果:

xlo=6.9314718055994528e-01 xxlo=1.9999999999999997e+00
xhi=6.9314718055994540e-01 xxhi=2.0000000000000005e+00
Delta x=1.1102230246251566e-16
Delta xx=6.6613381477509393e-16

已通过测试的其他处理器:AMD Ryzen 9 3950X,Intel i7-5557U,Intel i7-3770,Intel m7-6Y75。

但是据报道,一对夫妇失败了(xxlo == xxhi):Intel E5-2650和AMD EPYC 7401,碰巧都是服务器级机器。我没有直接访问这些证书的权限,但是在https://repl.it/languages/c上运行测试也失败了:

clang version 7.0.0-3~ubuntu0.18.04.1 (tags/RELEASE_700/final)
 clang-7 -pthread -lm -o main main.c
 ./main
xlo=6.93147180559945286e-01 xxlo=2.00000000000000000e+00
xhi=6.93147180559945398e-01 xxhi=2.00000000000000000e+00
Delta x=1.11022302462515655e-16
FAIL

我对结果的实际精度不太感兴趣,但对相对值更感兴趣。那我是不是错过了什么,还是只是错了?如果是错误的,是硬件舍入错误还是软件数学库甚至编译器/设置出现问题?我也有兴趣收集运行简单测试的结果,看看是否可以从该数据中得出其他结论。

c floating-point rounding ieee-754
1个回答
0
投票
如果导数为2.5,我希望输出范围在3到4之间。

请提供数字的十六进制;通过避免bin dec转换(在某些计算机上似乎也有缺陷),这应该是确定的。

我所说的话都没有使您的结论是服务器的硬件不一致,因此IEEE实施存​​在缺陷。

哦,还有一件事;通过查看日志后消除exp来检查优化器是否工作太辛苦。或者也许使用FMA,有时会给您[[更好

舍入错误。
© www.soinside.com 2019 - 2024. All rights reserved.