# 0.1+0.2 != 0.3
js中数字使用64位二进制标识(IEEE 754)
- 1个符号位
- 11个指数位
- 52个有效数字位
- 最大值:2^53 - 1
- 最小值:-2^53 + 1
# 小数表示
# 0.1
0.1二进制表示:0.0001100110011001100110011001100110011001100110011001101
- 计算方式(尾数0011无限循环)
- 0.1 * 2 = 0.2 取整数位0
- 0.2 * 2 = 0.4 取整数位0
- 0.4 * 2 = 0.8 取整数位0
- 0.8 * 2 = 1.6 取整数位1(1.6变成0.6)
- 0.6 * 2 = 1.2 取整数位1(1.2变成0.2)
- 0.2 * 2 = 0.4 取整数位0
- 0.4 * 2 = 0.8 取整数位0
- 0.8 * 2 = 1.6 取整数位1(1.6变成0.6)
- 0.6 * 2 = 1.2 取整数位1(1.2变成0.2)
# 整数表示
- 计算方式17(倒排10001)
- 17 / 2 = 8 ... 1 取余数1
- 8 / 2 = 4 ... 0 取余数0
- 4 / 2 = 2 ... 0 取余数0
- 2 / 2 = 1 ... 0 取余数0
- 1 / 2 = 0 ... 1 取余数1
- 计算方式16(倒排10000)
- 16 / 2 = 8 ... 0 取余数1
- 8 / 2 = 4 ... 0 取余数0
- 4 / 2 = 2 ... 0 取余数0
- 2 / 2 = 1 ... 0 取余数0
- 1 / 2 = 0 ... 1 取余数1
# 进制转换
// 二进制转10进制
parseInt(10001, 2) == 17
// 10进制转2进制
Number(0.1).toString(2) == 0.0001100110011001100110011001100110011001100110011001101
# 如何解决不相等问题
- 使用字符表示相加
- Number(0.1 + 0.2).toPrecision(12) == 0.3
- toPrecision表示取多少位有效位,12是经验所得
- 使用大数计算库
← 《斗地主》游戏演示demo async实现 →