Alb*_*ang 45 python numpy uint64
考虑以下展示uint64
数据类型的简短 numpy 会话
import numpy as np
a = np.zeros(1,np.uint64)
a
# array([0], dtype=uint64)
a[0] -= 1
a
# array([18446744073709551615], dtype=uint64)
# this is 0xffff ffff ffff ffff, as expected
a[0] -= 1
a
# array([0], dtype=uint64)
# what the heck?
Run Code Online (Sandbox Code Playgroud)
我对最后的输出完全感到困惑。
我期望 0xFFFF'FFFF'FFFF'FFFE。
这里究竟发生了什么?
我的设置:
>>> sys.platform
'linux'
>>> sys.version
'3.10.5 (main, Jul 20 2022, 08:58:47) [GCC 7.5.0]'
>>> np.version.version
'1.23.1'
Run Code Online (Sandbox Code Playgroud)
use*_*ica 40
默认情况下,NumPy 将 Python int 对象转换为 与numpy.int_
C 对应的有符号整数数据类型long
。(这个决定是在早期 Pythonint
也对应于 C 的时候做出的long
。)
没有足够大的整数 dtype 可以容纳numpy.uint64
dtype和 numpy.int_
dtype 的所有值,因此numpy.uint64
标量和 Python int 对象之间的运算会产生 float64 结果而不是整数结果。(uint64数组和 Python int 之间的操作可能表现不同,因为 int在此类操作中根据其值转换为数据类型,但a[0]
它是标量。)
第一次减法生成值为 -1 的 float64,第二次减法生成值为 2**64 的 float64(因为 float64 没有足够的精度来精确执行减法)。这两个值都超出了 uint64 dtype 的范围,因此转换回 uint64 进行赋值会a[0]
产生未定义的行为(继承自 C - NumPy 仅使用 C 强制转换)。
在您的计算机上,这恰好会产生回绕行为,因此 -1 回绕到 18446744073709551615 和 2**64 回绕到 0,但这并不能保证。您可能会在其他设置上看到不同的行为。评论中的人们确实看到了不同的行为。
Kel*_*ndy 12
a[0] - 1
是1.8446744073709552e+19
, 一个numpy.float64
. 那不能保留所有精度,所以它的值为 18446744073709551616=2 64。a
当用 dtype写回时np.uint64
,它会变成0
.
归档时间: |
|
查看次数: |
5224 次 |
最近记录: |