0%

IEEE 754 example

上篇文章(传送门)大家可能看得晕晕乎乎的,这篇就来举一些例子来帮助大家更直观的理解 IEEE 754 标准。

本文的举例对象仍然是单精确度浮点数(32位)。

首先回顾一下上篇最后的总结:

形式 指数 小数部分
全为 0 全为 0
非规约形式 全为 0 大于 0 小于 1
规约形式 1 到 2ᵉ - 2(不全为 0 也不全为 1) 大于等于 1 小于 2
无穷 2ᵉ - 1(全为 1) 全为 0
NaN 2ᵉ - 1(全为 1) 非 0

non-number

先看那三个简单且很好理解的特殊值:

  1. +0:0 00000000 00000000000000000000000

  2. -0:1 00000000 00000000000000000000000

  3. +infinity:0 11111111 00000000000000000000000

  4. -infinity:1 11111111 00000000000000000000000

  5. NaN:s 11111111 fraction

对于 NaN 来说,s 可 0 可 1,fraction 不全为 0 即可

normal number

规约形式的浮点数无疑是日常使用最多的。

例:将 -36.35 转为单精度二进制

  1. 整数部分转二进制

36₁₀ = (00100100)₂

  1. 小数部分转二进制

之前的文章说过小数怎么转二进制,再复习一下吧:

  • 小数部分乘以 2,取结果的整数部分,直到小数部分为 0 或者位数已达到所要求的精度为止
    • 0.35 x 2 = 0.7,整数部分为 0
    • 0.7 x 2 = 1.4,整数部分为 1
    • 0.4 x 2 = 0.8,整数部分为 0
    • 0.8 x 2 = 1.6,整数部分为 1
    • 0.6 x 2 = 1.2,整数部分为 1
    • 0.2 x 2 = 0.4,整数部分为 0
    • 0.4 x 2 = 0.8,从这里开始接下来无限循环 0 1 1 0 …

所以 0.35₁₀ = (01011001100110011000110…)₂

  1. 计算阶码

整数二进制.小数二进制 = 00100100.01011001100110011000110

移动小数点,使二进制变成 1.xxx * 2ⁿ 的形式:

1.0010001011001100110011000110 * 2⁵

指数的实际值是 5,单精度浮点数的固定偏移值为 127,所以指数域编码值为 5 + 127 = 132。

(132)₁₀ = (10000100)₂,所以阶码为 10000100

  1. 单精确度浮点数的尾数部分为 23 位,所以取 1.xxx 小数点后 23 位得到尾数部分为:

00100010110011001100110

  1. 负数符号位为 1,所以 -36.35 的单精度二进制表示为:

1 10000100 00100010110011001100110

例:00111001001010111110100000000000 转为小数

  1. 这是一个正数,是一个规约形式的浮点数,先分为三段

0 01110010 01010111110100000000000

  1. 计算指数的实际值

(01110010)₂ = 114₁₀,减去单精度浮点数的固定偏移值 127 得指数的实际值为 114 - 127 = -13

  1. 在尾数前加上隐藏的整数 1,然后转为 1.xxx * 2ⁿ 的形式:

1.01010111110100000000000 * 2⁻¹³

指数实际值为负数,所以整数部分为 0,小数部分二进制为:

0.000000000000101010111110100000000000

  1. 计算小数
1
2
1 * 2⁻¹³ + 1 * 2⁻¹⁵ + 1 * 2⁻¹⁷ + 1 * 2⁻¹⁹ + 1 * 2⁻²⁰ + 1 * 2⁻²¹ + 1 * 2⁻²² + 1 * 2⁻²³ + 1 * 2⁻²⁵
= 0.000163942575455

subnormal number

非规约形式的浮点数转换方法其实也很简单。因为非规约形式的浮点数整数部分为 0,所以非规约形式的浮点数转换就相当于上边的小数部分转二进制。

从上篇文章我们知道,非规约形式的浮点数指数实际值为 -126,即最终转为 0.xxx * 2⁻¹²⁶ 的形式,也就是说按照小数部分转二进制的方法,当出现第 127 个数时,这个数就作为尾数的第一个数,后边的依次补上,直到小数部分为 0 或者位数已达到所要求的精度为止。这个就不举例了。

同理,将非规约形式的浮点数转为小数将更简单。

例:00000000001000000000000000000000 转为小数

  1. 这是一个正数,是一个非规约形式的浮点数,先分为三段

0 00000000 01000000000000000000000

  1. 计算小数
1
2
2⁻¹²⁸
≈ 2.938735877056 * 10⁻³⁹

怎么样,对于 IEEE 754 的理解是不是更深刻了些?


欢迎关注我的其它发布渠道