Skip to content

IEEE 754

现代计算机中的浮点

基本格式

单精度

占用 32 位(4 字节)的二进制格式,其有效数字为 24 位(约 7 个十进制数)的精度

双精度

占用 64 位(8 字节)的二进制格式,其有效数字为 53 位(约 15 - 17 个十进制数)的精度

双重扩展

二进制格式至少占用 79 位(约 19 个十进制数)的精度

四倍精度

128 位(16 字节)的二进制格式(约 34 个十进制数)的精度

Decimal64 decimal128

十进制舍入

半精度

binary16 16 位浮点值

浮点数范围

64 位双精度 = 具有 53 位(包含一个隐含位)1 个符号位 11 个指数位的系数(指数可以表示的数 2^-1022 ≈ 2×10^-308 - 2^1024 ≈ 2 x 10^308)

字节序(Endian)

浮点数以大字节序形式表示,整数以小字节序表示

整数值的精度限制

  • 可以精确表示从-2^53 到 2^53(−9007199254740992 到 9007199254740992)的整数
  • 2^53 和 2^54 之间的整数= 18014398509481984,取整为 2 的倍数(偶数)
  • 2^54 和 2^55 之间的整数= 36028797018963968 舍入为 4 的倍数

内部表示

类型标志指数有效域总位数指数偏差位精度小数位数
16(IEEE 754-2008)1 个510161511〜3.3
321 个8233212724〜7.2
641 个115264102353〜15.9
x861 个1564801638364〜19.2
1281 个1511212816383113〜34.0

JavaScript 数表示

JavaScript 中采用 IEEE754 64 位浮点数标准,1 位表示标志位,11 位指数位,52 位有效域(有效数字 53 位,包含一位隐含位)

进制转换

二进制转换

整数

整数除余法

8 / 2 = 4 余 0 4 / 2 = 2 余 0 2 / 2 = 1 余 0

十进制 8 转换为二进制为 1000

小数

长乘法

0.1 _ 2 = 0.2 --- 0 0.2 _ 2 = 0.4 --- 0 0.4 _ 2 = 0.8 --- 0 0.8 _ 2 = 1.6 --- 1 0.6 _ 2 = 1.2 --- 1 0.2 _ 2 = 0.4 --- 0

依次类推

十六进制转换

二进制 -> 十六进制 2 ^ 4 = 16

3A(16) = 00111010(2) E7(16) = 11100111(2)

八进制转换

二进制 -> 八进制 2 ^ 3 = 8

65(8) = 110101(2) 17(8) = 001111(2)

计算机编码方式

机器数和真值

带符号位的机器数对应的真正数值称为机器数的真值

机器存储一个具体数字的编码方式

原码

符号位加上真值的绝对值,即用第一位表示符号,其余位表示值

反码

正数的反码是其本身,负数的反码是在其原码的基础上,符号位不变,其余各个位取反

减法 存在两个编码问题

补码

解决了两个编码问题[+0] [-0] 扩充了负数的最小值,以8位二进制为例[10000000, 01111111] = [-128, 127]

反码 + 1

负数二进制可以用补码表示

  • 补码具有两种表示形式:0:00000000(+0)和 11111111(-0)

二进制十进制(+1)

txt
    11111110 -1
+   00000010 +2
────────────
    100000000 0 ← 不是正确的答案
            1 +1 ← 加进位
────────────
  00000001 1 ← 正确答案
    11111110 -1
+   00000010 +2
────────────
    100000000 0 ← 不是正确的答案
            1 +1 ← 加进位
────────────
  00000001 1 ← 正确答案
  • 二进制正数转换负数 正数的二进制取反+1

e.q +2 = 00000010 = 取反 11111101 + 1 = 11111110(-2 的补码形式)

0.6 + 0.3 != 0.9

例子:说明浮点数相加之后的偏差原因

双精度浮点数,1位符号位,11位指数位,52位尾数

0.6 的二进制

0.6 * 2 = 1.2 --- 1 0.2 * 2 = 0.4 --- 0 0.4 * 2 = 0.8 --- 0 0.8 * 2 = 1.6 --- 1 依次类推

得到结果 0.6(10) = 0.1001 1001 1001(2) 指数表示法 0.6(10) = 1.001 1001 1001(2) * 2^-1

0.3 的二进制

0.3 * 2 = 0.6 --- 0 0.6 * 2 = 1.2 --- 1 0.6 * 2 = 1.2 --- 1 0.2 * 2 = 0.4 --- 0 0.4 * 2 = 0.8 --- 0 0.8 * 2 = 1.6 --- 1 以此类推

得到结果 0.3(10) = 0.011001(2) 指数对齐,右移一位 0.1001 1001 * 2^-1

指数对齐相加

0.6 + 0.3

1.0011 001... 0.1001 100... 1.1100 101...

0.11100 101 1 * 2^-1 + 1 * 2^-2 + ... + x^-52 得到近似结果 0.8999999999999999

解决方法

  • toFixed
  • toPrecision
  • 三方库
    • math.js
    • decimal.js
    • big.js

Released under the MIT License.