如何在 python 中将浮点数的位重新解释为 int

How to reinterpret bits of float as int in python

提问人:God I Am Clown 提问时间:5/14/2023 更新时间:5/15/2023 访问量:232

问:

我必须编写代码来打印浮点数位(十六进制)。对于 C++,首先想到的是 x 是存储原始数字的浮点变量。std::cout << std::hex << *reinterpret_cast<uint32_t*>(&x);

但是,当我在 python 中尝试同样的问题时,我只是想不出一种 python 式的方法来解决它(不允许使用非内置库)。我最好的尝试导致了这样的事情:

from ctypes import Union, c_uint32, c_float

class conversion(Union):
    _fields_ = [("int", c_uint32),
                ("float", c_float)]

v = conversion()
v.float = float(input())
print(hex(v.int)[2:])

这基本上是 C 代码。

那么,有没有更多的“python”方法可以做到这一点呢?最近的 python 版本是否引入了对这种情况有用的内容?

Python 浮点整

评论

1赞 user2357112 5/14/2023
docs.python.org/3/library/struct.html
0赞 Samwise 5/14/2023
我的看法是,如果你正在做一些足够接近金属的事情,你需要检查浮点数的硬件表示,那么 Python 不是一个好的语言选择。
0赞 Kelly Bundy 5/14/2023
这甚至看起来都不正确,因为你丢失了一半的位(从 64 位到 32 位)。这个练习的目的是什么?为什么要“重新解释位”?请显示输入和所需输出的示例。
0赞 Eric Postpischil 5/15/2023
在 C++ 中使用 a 不是获取对象位的正确方法。您可以简单地使用 .reinterpret_caststd::memcpy
0赞 God I Am Clown 5/15/2023
对于上下文:没有接近金属的东西,只是一个抽象的任务。示例:输入“-21.25”,输出“C1AA0000”。不知道 ctypes 的浮点大小是 64 位,我只需要处理单精度数字。关于访问位,这实际上是首先想到的,没有任何包含和东西。不认为这是正确的

答:

0赞 yaroslavsokolov 5/15/2023 #1

首先,您的实现不准确,因为 CPython 实现中的浮点数是双精度浮点类型(c++ double),因此它的大小为 64 位。您必须使用c_uint64和c_double才能获得最佳效果

您可以使用 struct 模块将 float 打包到 Python bytes 对象,然后将其解压缩为整数值:

import struct
float_to_hex = lambda f: hex(struct.unpack('@Q', struct.pack('@d', f))[0])
print(float_to_hex(123.45)) # Output: 0x405edccccccccccd

“Python”方式:你可以只使用该方法,但结果会有所不同:float.hex()

print(123.45.hex()) # Output: 0x1.edccccccccccdp+6

评论

0赞 Eric Postpischil 5/15/2023
Re “python 中的浮点数是双精度的......它的大小是 64 位“:Python 没有正式的规范或标准,并且有这样的文档将其留给底层硬件来确定浮点格式。
0赞 user2357112 5/15/2023
如果你看一下输出,你会看到它打印的东西与所需的输出完全不同。hexfloat 表示法很方便,但这不是提问者想要的。float.hex()
0赞 Sam Mason 5/15/2023
@EricPostpischil在实践中,Python 使用IEEE754 64 位二进制浮点数(唯一已知的例外是使用 32 位浮点数的 micropython)。当情况并非如此时,预计会出现破损。stackoverflow.com/q/70184494/1358308
0赞 Eric Postpischil 5/15/2023
@SamMason:你的观点是什么?我们应该假设,因为 IEEE-754 binary64 现在几乎无处不在,我们应该假设它总是无处不在?或者因为它现在几乎无处不在,我们应该声明它被 Python 使用,而不警告人们它并不总是被 Python 使用?这些都不是好的工程实践。当事实是 X 并不总是 Y 时,说“X 是 Y”简直是不好的做法。
0赞 Sam Mason 5/15/2023
@EricPostpischil,我以“在实践中”为前缀,以表明如果您只想要一些适用于当前版本的 CPython 的简单东西,那么答案所暗示的可能没问题。