如何将大数(例如 1.23e29)转换为 IEEE 754 单精度浮点格式?
Posted
技术标签:
【中文标题】如何将大数(例如 1.23e29)转换为 IEEE 754 单精度浮点格式?【英文标题】:How do I convert a big number (e.g. 1.23e29) to IEE 754 single-precision floating-point format? 【发布时间】:2016-04-02 15:41:11 【问题描述】:我通过here 学习了如何从十进制转换为 IEEE 754,但我不知道如何转换一个非常大的数字,而不必通过帖子中解释的方法将其全部除。
例如,我必须将 -1.5845632e29 转换为 IEEE 754 单精度浮点,有没有比获取这个大数的 log base 2 更简单的方法?
【问题讨论】:
大数字可能不适合 IEEE-754 格式。为什么不直接使用 bignum 库? -1.5845632e29 在 IEEE-754binary32
数字可表示的范围内。为什么计算 log2 来获得指数是个问题?在最坏的情况下,它可以通过将每一步中的数字减半的迭代来计算,直到结果在 [1,2) 范围内。
准确地执行基本转换是一个难题,我建议您参考以下论文作为起点:William D.Clinger,“如何准确读取浮点数。 " ACM SIGPLAN 通知 39.4 (2004): 360-371.
【参考方案1】:
以下示例使用 Python。请注意,这假设您对快速计算方法比非常准确的答案更感兴趣。
你不能简单地在整个事情上使用 log base 2,这只会给你一个合理的指数。然后要找到尾数,您可以拆分指数结果的小数部分并再次提高 2 的幂,然后乘以 2 的尾数位数的幂。该标志需要单独处理。
以下产生一个指数(没有偏差)和尾数(1+23 位,以十六进制显示):
math.log(1.5845632e29, 2)
96.99999995421683
hex(int(math.floor(2**0.99999995421683*2**23)))
'0xffffff'
为了结合所有这些,屏蔽隐含的尾数之一,移动指数+偏差,并取符号位:
hex((0xffffff & 0x7fffff) | ((96+127) << 23) | (1 << 31))
上述技术有一些限制 - 它不能捕获异常并且可能存在准确性问题。请注意,对于小数字,您确实需要使用负分数来计算尾数。要更精确地执行此操作或针对不同的格式,您可能必须在没有浮点数学函数的情况下完成整个操作。
如果您的工具或语言可以支持任意大的整数,那么这里是一个可以很好地工作的技术的粗略步骤。这在 Python 中很容易,例如C 你需要特殊的库。
-
将数字写为实际值的大整数
在它下面找到两个的幂
乘以 2 到所需尾数位数的幂,应用任何所需的舍入,然后右移指数。
通过添加偏差计算 IEEE 指数
【讨论】:
以上是关于如何将大数(例如 1.23e29)转换为 IEEE 754 单精度浮点格式?的主要内容,如果未能解决你的问题,请参考以下文章