gpt4 book ai didi

python - 为什么 numpy 的 asinh 输出会因操作系统而异?

转载 作者:太空宇宙 更新时间:2023-11-04 02:13:52 24 4
gpt4 key购买 nike

我试图在不同的操作系统上保持一致的浮点计算结果,但在较新的系统上进行测试时,我遇到了关于 numpy 和 arcsinh 的奇怪回归。这是一个最小的工作示例,它在不同系统中表现不同。

#!/usr/bin/env python
import struct

from numpy import (array, arcsinh, float32)


def float_to_hex(f):
return hex(struct.unpack('<I', struct.pack('<f', f))[0])


numpy_result = arcsinh(array([3.0], dtype=float32))[0]
print("asinh(3.0):", numpy_result, float_to_hex(numpy_result))

在 Centos 7 和 Ubuntu 16.04 上,我得到以下结果:asinh(3.0): 1.8184464 0x3fe8c2da

在 Ubuntu 18.04(和同事所说的 Windows)上,我得到以下结果:asinh(3.0): 1.8184465 0x3fe8c2db

如果能理解为什么会发生这种情况以及如何跨系统获得一致的结果,那就太好了。理想情况下坚持使用 32 位浮点解决方案。是否有一些我忽略了跨操作系统变化的 numpy 选项?

值得注意的是,我无法用 C 程序重现它。使用 GLIBC 的 asinh(32 位 float 3.0)我总是得到 1.8184465 的新结果,它是 0x3fe8c2db 十六进制表示,无论我在什么系统上。这似乎是特定于 numpy 的。

我的工作 C 示例:

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

int main() {
float value = asinhf(3.0f);
unsigned int hexValue = *(unsigned int *)&value;
printf("Plain value: %.7f\n", value);
printf("Hex value: 0x%8x\n", hexValue);
return 0;
}

我还可以验证跨系统使用的是完全相同的 numpy 版本。在本例中为 1.15.3。 numpy 包是从 wheels 到处安装的,因此安装了相同的共享对象库。为了我的理智,我通过在所有系统上对所有库运行 file 操作来仔细检查这些库。

我相信根据 IEEE 754,最后一位有效数字 5(arcsinh 为 3.0)是正确的,因为它应该从零开始舍入。然而,结果一致的解决方案对我来说更为重要。

感谢您的宝贵时间。

最佳答案

所以我发现了为什么不同系统的答案是不同的,以及我以前没有看到它的原因。但是,我仍然不确定如何获得一致的结果。

正如 Mark Dickinson 在评论中指出的那样,我忽略了 gcc 正在使用 MPFR(具有正确舍入的多精度浮点)执行编译时优化。在生成的二进制文件上运行 ldd 表明 libm 根本没有被动态加载。我用 clang 重新编译了我的 C 示例,并在 libm 中动态链接,你瞧,我得到的结果与我通过 python/numpy 跨系统完成的结果完全相同。结果是 asinhf(3.0f); 在旧系统上四舍五入,在新系统上四舍五入。

所以这看起来像是某个时候的 libm 库更新。

具体而言,至少在 GLIBC 的 2.23 和 2.27 之间发生了变化。

如果有人对跨系统进行一致舍入有任何建议,我将不胜感激。我怀疑无论旧系统的精度如何,都可能存在不正确的舍入。

感谢您的宝贵时间。

关于python - 为什么 numpy 的 asinh 输出会因操作系统而异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53088270/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com