我想要这样一个函数:
>>> binary128_to_hex("1.0")
'3fff0000000000000000000000000000'
我目前在x86笔记本电脑上使用C和qemu-aarch64
来完成这项工作。我如何“本地”实现这样的功能?我发现numpy.float128
和struct
包没有帮助。
此外,多亏了Mark Dickinson’s answer,我想出了进行反向转换的办法(尽管只处理规范化的值):
import decimal
def hex_to_binary128(x: str):
with decimal.localcontext() as context:
context.prec = 34
x = int(x, 16)
significand_mask = (1 << 112) - 1
exponent_mask = (1 << 127) - (1 << 112)
trailing_significand = x & significand_mask
significand = 1 + decimal.Decimal(trailing_significand) / (1 << 112)
biased_exponent = (x & exponent_mask) >> 112
exponent = biased_exponent - 16383
f = significand * decimal.Decimal(2) ** exponent
return f
if __name__ == "__main__":
print(hex_to_binary128("0000ffffffffffffffffffffffffffff"))
# 3.362103143112093506262677817321752E-4932
这里有一整套可能的解决方案,这取决于您希望允许的复杂性、您需要的性能、您准备依赖外部库的程度,以及您需要在多大程度上处理IEEE 754特殊情况(溢出、低于正常值、有符号零等)
这里有一些工作代码,我希望能给出一个合理的折衷方案。它(a)相当简单,(b)不依赖于标准库之外的任何东西,(c)处理次正常值、有符号的零和溢出相当好(但不尝试解释像“inf”或“nan”这样的字符串),并且(d)可能具有糟糕的性能。但如果你只对随意使用感兴趣,它可能就足够了
代码的思想是通过使用
fractions.Fraction
解析器解析Fraction
对象的字符串输入来避开所有解析困难。然后,我们可以分离Fraction
对象并构造我们需要的信息我将分三部分介绍解决方案。首先,我们需要的一个基本工具是计算正
Fraction
的二进制指数(换句话说,base-2 log的下限)的能力。下面是代码:这很简单:分子和分母的位长度之差
e
要么给我们正确的指数,要么比它应该的大一。为了弄清楚这一点,我们必须将分数的值与2**e
进行比较,其中e
是我们的测试指数。我们可以直接这样做,将2**e
计算为Fraction
,然后进行比较,但是使用一些位移位会更有效,所以我们就是这么做的接下来,我们定义一些基本常量和派生常量,这些常量描述IEEE 754 binary128格式。(通过将这些常量替换为binary64格式的常量并检查结果是否如预期的那样,可以很容易地测试下面的代码。)格式的位宽度为
128
;精度是113
,其他一切都可以从这两个值中推导出来这其中大部分应该是不言自明的。常量
INF
是正无穷大常量的位表示,我们将使用它来处理溢出最后,这里是主要功能:
上面有两个狡猾的花招值得特别提及:首先,当从
exponent
和significand
使用表达式(exp - EMIN << PRECISION - 1) + significand
构造bits
时,我们不做任何特殊的处理亚正常。尽管如此,代码仍能正确地处理次正常值:对于正常情况,指数值exp - EMIN
实际上比它应该的值小一个,但在执行加法时,有效位的最高有效位最终使指数字段递增。(因此,重要的是我们使用+
而不是|
来组合指数块和有效位。)另一个观察结果是
exp
的选择确保了round
调用的参数严格小于2**PRECISION
,但是round
调用的结果可能恰好是2**PRECISION
。在这一点上,您可能希望我们必须测试这种情况,并相应地调整指数和有效位。但是,同样地,不需要特别处理这种情况-当使用(exp - EMIN << PRECISION - 1) + significand
组合字段时,我们得到了指数字段的额外增量,并且所有结果都正确,即使在最后溢出到无穷大的拐角情况下也是如此。IEEE754二进制交换格式的优雅设计使这种欺骗成为可能下面是在几个示例上测试上述代码的结果:
相关问题 更多 >
编程相关推荐