[-1, +1]我读取了一些以IEEE32 浮点数存储的数据
[-1, +1]
A = numpy.fromstring(data, dtype = numpy.float32)
但是我不想将数组保留为float32,而是保留为 32 位整数(以 为单位[-2^31, +2^31-1])。
float32
[-2^31, +2^31-1]
我尝试简单地做:
A = numpy.fromstring(data, dtype = numpy.int32) # that's wrong!
但它给出了一个糟糕的结果。(可能是由于乘法常数错误,或者是其他原因?)
如何将 [-1,1] 内的 IEEE32 浮点数数组读入 32 位整数数组[-2^31, +2^31-1]?
PS:这是可行的,但我想避免这种幼稚的方法:
A = numpy.fromstring(data, dtype = numpy.float32) A *= 2^31 A = int(A) # convert the data type to int
如果可能的话,因为我想象有一个更聪明的方法来做到这一点,无需乘法,而只需按位执行…
要将存储为 IEEE 32 位浮点数(float32)的数组 [-1, +1] 转换为对应的 32 位整数(int32)数组 [-2^31, +2^31-1],可以使用按位操作(避免显式乘法)。这可以通过以下步骤实现:
int32
将浮点数通过视图转换为整数。由于 float32 和 int32 都是 32 位宽的类型,可以利用 numpy 的 .view() 方法在内存中重解释数据类型,从而避免显式的逐个乘法和数据拷贝。
.view()
import numpy as np # 假设数据是以 IEEE float32 形式存储的 [-1, +1] 浮点数组 data = np.random.uniform(-1, 1, 10).astype(np.float32).tobytes() # 读取数据为 float32 数组 A = np.frombuffer(data, dtype=np.float32) # 将数据从 float32 转换为 int32 范围 [-2^31, +2^31-1] B = np.round(A * (2**31 - 1)).astype(np.int32) # 输出结果 print("原始浮点数据:", A) print("转换后的整数数据:", B)
.astype(np.int32)
简单地将 float32 直接转为 int32,数据会被截断,而不是映射到目标范围。这是因为: 1. float32 的值范围与 int32 不一致。 2. 转换时需要将 [-1, +1] 按比例映射到 [-2^31, +2^31-1]。
浮点数的范围是 [-1, 1],而整数的范围是 [-2^31, 2^31-1]。直接按位转换会导致错误结果,除非数据本身已经编码了这种比例关系。乘法确保数据被正确映射。
[-1, 1]
[-2^31, 2^31-1]
如果数据已经以比例编码,可以通过直接 reinterpret_cast 的方式操作:
# 直接视图转换(仅适用于特定数据布局) B = A.view(np.int32)
但请注意,这种方法仅适用于 原始数据已经存储为符合目标整数表示的布局 的场景。如果你的数据不是这种比例编码,那么使用乘法映射的方式是必要的。