Python的float数据类型确实使用了双重精度(64位)。但是,对于我的具体实现(通过OSC发送带有类型标记的值),我希望区分可以表示为(32位)单精度浮点数和(64位)双精度浮点数的值。
更确切地说,我想做这样的事情:
if isdouble(value):
binary=struct.pack('>d', value)
else:
binary=struct.pack('>f', value)是否有可行的方法来达到这个目标?
发布于 2013-11-14 13:34:17
我建议只使用float进行尝试,如果失败(由于范围溢出),请使用双重版本:
try:
binary = struct.pack('>f', value)
except OverflowError:
binary = struct.pack('>d', value)范围是唯一的方面,在你的问题是完美的意义。
如果涉及到精确性,您的问题就失去了意义,因为正如您所说的,Python总是在内部使用双倍,即使是简单的3.3也是,打包和解压缩为浮点,之后只有3.299999952316284:
struct.unpack('>f', struct.pack('>f', 3.3))
(3.299999952316284,)因此,几乎没有任何一个双可以表示为一个浮点。(通常,没有一个不是int,或者最初是从浮点数中出来的。)
但是,您可以检查数字的打包-解压缩版本是否等于原始版本,如果是,请使用浮点版本:
try:
binary = struct.pack('>f', value)
if struct.unpack('>f', binary)[0] != value:
binary = struct.pack('>d', value)
except OverflowError:
binary = struct.pack('>d', value)发布于 2013-11-14 13:21:10
您可以测试范围,如果您不介意丢失一点精度(请参阅阿尔菲的回答):
def isdouble(value):
return not (1.18e-38 <= abs(value) <= 3.4e38)或者倒转来测试单个精度:
def issingle(value):
return 1.18e-38 <= abs(value) <= 3.4e38:这将防止引发OverflowError异常,另一种方法就是抓住它。
请注意,float('-0')、float('+0')、float('inf')、float('-inf')和float('nan')将使用这些测试作为双倍进行测试;如果您希望这些测试存储在4个字节而不是8个字节中,那么显式地测试它们。
发布于 2013-11-15 02:59:27
您可以通过将浮点数转换为double,并将结果与x进行比较,来检查double x是否完全可以表示为浮点数。
所有浮点数都是双倍表示的,因此后向转换不涉及舍入。结果将等于原始的双当且仅当浮点数等于那个双倍。
https://stackoverflow.com/questions/19978674
复制相似问题