Mac 与 Linux 上不同的 numpy 溢出行为

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

我在 Mac 和 Linux 上使用相同版本的 numpy 时遇到了不同的溢出行为。 MWE:

import numpy as np
arr = np.arange(0, 2 * 4e9, 1e9, dtype=float)
print(arr.astype(np.uint32))
print(np.__version__)

Mac(Python 3.9.13):

array([         0, 1000000000, 2000000000, 3000000000, 4000000000,
        705032704, 1705032704, 2705032704], dtype=uint32)
'1.22.4'

Linux(Python 3.9.7):

array([         0, 1000000000, 2000000000, 3000000000, 4000000000,
                0,          0,          0], dtype=uint32)
'1.22.4'

我更喜欢预期翻转的“Mac”行为(而不是将溢出值强制为 0),因此我想知道如何针对 Linux 版本修复此问题。

python numpy integer-overflow
1个回答
1
投票

我相信这是由于 numpy 的底层

C
实现造成的,这可能会触发未定义的行为,而用于 numpy 的 linux 和 mac 发行版的编译器对此的处理方式有所不同。

查看处理类似主题的 cast float to unsigned int in C with gcc,我们还可以看到指向第 51 页所述的 C 标准的链接

6.3.1.4 实数浮点数和整数
1 当实浮点类型的有限值转换为_Bool以外的整数类型时,小数部分将被丢弃(即该值被截断为零)。如果整数部分的值不能用整数类型表示,则行为未定义。61)

一种可能性是我猜你尝试不同的编译器来编译你自己的 numpy 版本并检查行为。或者,由于您想要翻转行为,您可以尝试首先转换为较大宽度的无符号整数类型,然后转换为较小宽度,因为无符号整数转换总是进行翻转

6.3.1.3 有符号和无符号整数
1 当整数类型的值转换为_Bool以外的其他整数类型时,如果 该值可以用新类型表示,它没有改变。
2 否则,如果新类型是无符号的,则通过重复添加或来转换该值 比新类型可以表示的最大值减一 直到该值在新类型的范围内。60)

import numpy as np
arr = np.arange(0, 2 * 4e9, 1e9, dtype=float)
print(arr.astype(np.uint64).astype(np.uint32))
print(np.__version__)
© www.soinside.com 2019 - 2024. All rights reserved.