(有人应该仔细检查这个答案,特别是边界情况和负值的四舍五入。另外,我写它是为了四舍五入。为了重现 C 的转换,这应该改为向零舍入。)
本质上,该过程是:
将 32 位分为 1 个符号位 ( s )、8 个指数位 ( e ) 和 23 个有效位 ( f )。我们将它们视为二进制补码整数。
如果e为 255,则浮点对象要么是无穷大(如果f为零)要么是 NaN(否则)。这种情况下不能进行转换,应该报错。
否则,如果e不为零,则将 2 24添加到f。(如果e不为零,则有效数在其前面隐含 1 位。添加 2 24使该位在f中显式。)
从e中减去 127 。(这会将指数从其偏差/编码形式转换为实际指数。如果我们要对任何值进行一般转换,我们将不得不处理e为零时的特殊情况:减去 126 而不是 127。但是,因为我们只是转换为整数结果,我们可以忽略这种情况,只要这些微小输入数字的整数结果为零。)
如果s为 0(符号为正)且e为 31 或更大,则该值溢出有符号 32 位整数(它为 2 31或更大)。无法进行转换,应该报错。
如果s为 1(符号为负)且e大于 31,则该值溢出有符号 32 位整数(小于或等于 -2 32)。如果s为 1,e为 32,并且f大于 2 24(设置了任何原始有效位),则该值溢出有符号 32 位整数(小于 -2 31;如果原始f为零,它将恰好是 -2 31,不会溢出)。以上任何一种情况都无法进行转换,应该报错。
现在我们有一个s、一个e和一个f来表示一个不会溢出的值,所以我们可以准备最终值。
如果s为 1,则将f设置为-f。
指数值适用于 1(包括)和 2(不包括)之间的有效位,但我们的有效位从 2 24位开始。所以我们必须对此进行调整。如果e是 24,我们的有效位是正确的,我们就完成了,所以返回f作为结果。如果e大于 24 或小于 24,我们必须适当地移动有效数。此外,如果我们要将f向右移动,我们可能必须对其进行四舍五入,以将结果四舍五入为最接近的整数。
如果e大于 24,则将f左移e -24 位。返回f作为结果。
如果e小于 -1,则浮点数在 -½ 和 ½ 之间,互斥。返回 0 作为结果。
否则,我们将f右移 24 -e位。但是,我们将首先保存舍入所需的位。将r设置为将 f 转换为无符号 32 位整数并将其左移 32-(24- e ) 位(等效地,左移 8+ e位)的结果。这需要将移出f的位(如下)并在 32 位中“向左调整”它们,因此我们有一个固定的起始位置。
将f右移24 -e位。
如果r小于 2 31,则什么也不做(这是向下舍入;移位截断位)。如果r大于 2 31,则将f加一(这是向上取整)。如果r等于 2 31 ,则将f的低位添加到f。(如果f是奇数,则将f加一。在两个相等接近的值中,这将舍入为偶数。)返回f。