我正在使用Numpy和Python。我需要复制数据,没有np. uint64和np.float64之间的数字转换,例如1.5
我知道float. hex,但输出格式与uint64相差甚远:
In [30]: a=1.5
In [31]: float.hex(a)
Out[31]: '0x1.8000000000000p+0'
我也知道其他方式的各种字符串输入例程。
有人能提出更直接的方法吗?毕竟,它只是简单的复制和类型更改,但是python/numpy在转换数据的过程中似乎非常严格。
使用中间数组和frombuffer
方法将一种数组类型“转换”为另一种:
>>> v = 1.5
>>> fa = np.array([v], dtype='float64')
>>> ua = np.frombuffer(fa, dtype='uint64')
>>> ua[0]
4609434218613702656 # 0x3ff8000000000000
由于frombuffer
在原始缓冲区中创建了一个视图,因此即使对于重新解释大型数组中的数据也是有效的。
因此,您需要的是将内存中表示float64的8个字节视为一个整数。(将这个int64数字表示为十六进制字符串是另一回事——它只是它的表示)。
与stdlib的ctype捆绑在一起的结构和联合功能可能对您来说很好-不需要numpy。它有一个与C语言联合非常相似的Union类型,并允许您这样做:
>>> import ctypes
>>> class Conv(ctypes.Union):
... _fields_ = [ ("float", ctypes.c_double), ("int", ctypes.c_uint64)]
...
>>> c = Conv()
>>> c.float = 1.5
>>> print hex(c.int)
0x3ff8000000000000L
内置的“十六进制”函数是一种获取数字十六进制表示的方法。
您也可以使用struct
模块:将数字打包为双精度字符串,并将其解压缩为int。我认为它的可读性和效率都低于使用ctype Union:
>>> inport struct
>>> hex(struct.unpack("<Q", struct.pack("<d", 1.5))[0])
'0x3ff8000000000000'
但是,由于您使用的是numpy,您可以简单地更改数组类型,“动态”,并将所有数组操作为0副本的整数:
>>> import numpy
>>> x = numpy.array((1.5,), dtype=numpy.double)
>>> x[0]
1.5
>>> x.dtype=numpy.dtype("uint64")
>>> x[0]
4609434218613702656
>>> hex(x[0])
'0x3ff8000000000000L'
这是迄今为止最有效的方法,无论您获取float64数字的原始字节的目的是什么。