如何将大数(例如 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-754 binary32 数字可表示的范围内。为什么计算 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 单精度浮点格式?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2005:将 varchar 值“1.23E-4”转换为十进制失败

如何将一串大数转换为整数?

如何在 C++ 中将大数字符串转换为整数?

将 IEEE754 转换为十进制的方程(标准化形式)

IEEE-754 蟒蛇

如何将 UI 控件的双数据值格式化为数字,例如 1234 到 1.23K? [复制]