复制内部格式float64 uint64

时间:2014-07-09 05:57:31

标签: python numpy uint64

我正在使用Numpy和Python。我需要复制数据,没有np.uint64和np.float64之间的数字转换,例如1.5 <-> 0x3ff8000000000000

我知道float.hex,但输出格式距离uint64很远:

In [30]: a=1.5
In [31]: float.hex(a)
Out[31]: '0x1.8000000000000p+0'

我也知道其他方式的各种字符串输入例程。

有人可以建议更直接的方法吗?毕竟,它只是简单的复制和类型更改,但python / numpy似乎在转换数据的过程中非常严格。

2 个答案:

答案 0 :(得分:2)

使用中间数组和frombuffer方法来&#34;施放&#34;一个数组类型到另一个:

>>> v = 1.5
>>> fa = np.array([v], dtype='float64')
>>> ua = np.frombuffer(fa, dtype='uint64')
>>> ua[0]
4609434218613702656      # 0x3ff8000000000000

由于frombuffer创建了一个原始缓冲区的视图,因此即使重新解释大型数组中的数据,这也是有效的。

答案 1 :(得分:1)

所以,你需要的是在内存中看到表示float64的8个字节为整数。 (将此int64数字表示为十六进制字符串是另一回事 - 它 只是它的代表性。)

与stdlib的ctypes捆绑在一起的Struct和Union功能 可能对你很好 - 不需要numpy。它有一个有效的联盟类型 很像C语言联盟,并且允许你这样做:

>>> 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模块:将数字打包为字符串作为double,并将其解压缩为int。我认为它比使用ctypes 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数字的原始字节的目的是什么。