整数

在讲浮点数在二进制的表示之前,我们要先了解整数在二进制中的表述。

其实和十进制一样,只不过在十进制中,每位数的权是 (where i is the index starting from 0) 那么在二进制中则是以 作为权。

最常见的整数即为 int32 ,长度为 4 bytes, 32 bits,但其中最高位为 sign bit , 带有 的权(例:100...000 共 32 bit,值为 -2^31 = -2,147,483,648 )。由此看来,最高位还兼有表示正负的功能(最高位是 1 为负,0 为正),而其余位照常表示正权值,也就是说,INT_MIN = 100...000 = -2^31

但这样会带来一个问题,0 这个数,在二进制中应表示为 000...000 ,那就说明 0 在此处被看做了一个正数,由对称性得, INT_MAX = 011...111 = 2,147,483,647 ,或者在数学上

浮点数

那要表示 小数 ,也就是浮点数,最显而易见的做法就是仿照十进制的做法,取 16 bit 表示小数点前面部分(characteristic),权为 ;取 16 bit 表示小数点后面部分(mantissa),权为 ]。

显然,这样会带来严重的空间浪费,所以,计算机科学家们设计了一种巧妙的做法,能用 32 bit 表示 to 的范围 (1.2E-38 to 3.4E+38),但是代价是存在误差,比如著名的 0.1 + 0.2 = 0.30000000000000004Floating Point Math

根据 bit 的排列不同,共有四种形式,一一介绍

General

先不纠结数值,先看 bit 的排列,分为三组,符号位 (sign bit),指数部分 (exponent bits),和有效部分 (significant bits / fraction bits)。

整体思想是,符号位 S 为 1 表示负数, 0 表示正数,由指数部分算出 E ,由有效部分算出 M 。 最终结果可以表示为

看出点什么了吗,本质上是科学计数法呀!

我们在十进制中表示为 ,自然也能在二进制中表示 , 这其中的 ,便是通过 8 exponent bits 表示的。

而我们要表示小数, 自然也要有正有负(负的情况才有小数呀),而此时的 exponent bits 可是没有符号的(最高位的符号是整个数的符号,而不是 exponent 的符号),所以最直接想到的就是像 int 一样减去一半,这样就有正有负了。此时 exponent bits 表示的范围从 。 此时我们不是像 int 一样最高位置为符号位,而是像 uint 一样 literally 的读取它,再做减法。

我们把这个要减去的数叫做 bias ,它的数值为 (其中 k 为 exponent bits 位数,8 for float32 and 16 for double64, 即 127 for float32 and 1023 for double64) 。

此时又有特殊的地方,当值为 128(即 exponent bits 全为 1 时)和值为 -127 (exponent bits 全为 0 时),被设定为了特殊值(见上图的 2 和 3),需要特殊处理,去掉这两个值后,现在它所能表示的大体范围就变成 了。 现在我们取 exponent bits 的结果为 ,公式中的 可看作

大体范围是因为具体数值是由 fraction 部分确定的,在十进制中,取前面表示数值部分为 的选取规则是 ,那么在二进制中,我们选取 …??? wait a second!

在二进制中,只有一个数满足这个条件,那就是 1 。所以小数点前面是确定的,是 x 的值由正常二进制小数组成。也就是说,significant bits/fraction bits 全部当作小数点右边的数正常计算即可(每位权值为 ),把这个小数叫做 ,最后 即可正确表示。

Case 1: Denormalized Values

  • 出现情况

    • exponent bits 全为 0
    • 为什么是 1 - Bias?不是 ,即 ?
      • 现在的 exponent bits 全为 0,对于下一个数,如果当 exponent bits 不全为 0 ,那就是从 1 开始喽,所以就是 1 - Bias 喽,主要为了更平滑地从此处的 Denormalized 过渡到之后的 Normalized。
    • 为什么不 + 1 ?
      • 用于表示非常接近 0 的数。
      • 如果 + 1, 0 要怎么表示呢?
        • 实际上有两个零,+0.0, -0.0,区别只是 sign bit 不同
  • 最终结果 V:

Case 2: Normalized Values

  • 出现情况

    • exponent bits 不全为 0 且不全为 1
  • 最终结果 V:

这下是不是就很 Normal 了?

Case 3: Special Values

  • When the exponent field is all ones
    • When the fraction field is all zeros, the resulting values represent infinity
    • When the fraction field is nonzero, the resulting value is called a NaN, short for “not a number.”

当 exponent bits 全为 1 时,显然是过大了的情况,这时候要不是无限(Infinity),要不出现了错误,结果不是个数字 (NaN)

结尾的啰嗦

  • 这个标准叫做 IEEE 754,其实哪怕忘了具体内容,也可以把这个名字搬出来直接精神胜利!

  • 浮点数之间的比较

    • 由于这种特殊的表示方法,我们有了一个非常便捷比较两个浮点数的方法,直接先比较 sign bits,再看 exponent bits,最后才比较具体的 significant bits。
  • 类似的,64 bits ,128 bits 的浮点数,可以举一反三

  • 还有个麻烦的地方是浮点数的 Rounding

  • Warning:Operations on denormalized floating-point can be tens to hundreds of times slower than on normalized floating-point. This is because many processors can’t handle them directly and must trap and resolve them using microcode.

  • Example