我知道有多种方法可以使用书面库读取 IEEE 754 float 的每一位。
我不希望这样,我希望能够手动将十进制 float 转换为基于 IEEE 754 的二进制表示形式。
我了解 IEEE 754 的工作原理,并且我只是尝试应用它。
我在这里问这个问题只是想看看我的方法是正常的还是愚蠢的,我也想知道PC如何快速做到这一点。
如果给我一个字符串中的十进制 float ,我需要弄清楚E是什么以及M是什么。
取出两部分:整数部分
i
和小数部分f
。处理
f
。我不断乘以2
并得到整数部分(0或1)并删除整数部分然后重复,直到它变成0将
i
转换为位。这很容易,我只需不断地mod 2
和div 2
即可获得i
的所有位。
例如,转换f
部分
0.390625 * 2 = 0.78125 0
0.78125 * 2 = 1.5625 1
0.5625 * 2 = 1.125 1
0.125 * 2 = 0.25 0
0.25 * 2 = 0.5 0
0.5 * 2 = 1 1
0
在本例中,0.390625
的临时位为 0 1 1 0 0 1
。
现在,我有了 i
和 f
的位。
如果 i
的所有位均为 0,则在 f
的位上,我将其向左移动,直到第一个 1
消失,根据M
的 默认隐藏 1
。我得到M
,然后给出转移到E的值,当然考虑到E
的基线。
如果i
不为0,那么我连接两个位部分并计算需要执行多少次shift_right才能使连接的位为1,然后将此值赋予E
我想我的步骤都没有错。但我觉得非常麻烦。
有没有简单、干净的方法?
PC 是如何做到的?
最佳答案
查看 Frama-C 中的文件 src/lib/floating_point.ml
和 src/lib/floating_point.mli
。它们实现了单精度和 double 从十进制表示形式到 float 的转换(由于 double rounding 问题,您无法从后者获得前者),无需任何外部库。这些文件受 LGPL 2.1 管辖。此实现是几篇从 this one 开始的博客文章的主题。并继续this one .
这可能接近最简单的转换函数,因为在编写这个函数时,我没有性能限制,只希望保持代码尽可能简单和正确,而不希望依赖于现有的库例如MPFR。
...
type parsed_float = {
f_nearest : float ;
f_lower : float ;
f_upper : float ;
}
val single_precision_of_string: string -> parsed_float
val double_precision_of_string: string -> parsed_float
...
关于algorithm - 基于 IEEE 754 手动将十进制浮点转换为位表示的最简单方法,无需使用任何库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22962040/