Appearance
前言
以前只知道0.1 + 0.2 !== 0.3,不知道为什么,而且解决方案也很粗糙,就是简单的扩大, 将小数部分隐藏掉
为什么js会出现 0.1 + 0.2 !== 0.3
js数字的存储按照64位双精度浮点数保存,小数和整数都是。部分小数在转换成二进制时,总是无限循环的(整数部分除2取余,小数部分是乘2,递归的对小数部分继续处理)。 所以即使再多位也没法保存一个0.1,0.1 保存在内存中就会丢失部分信息,一个不准确的值和另一个不准确的值相加自然不会等于另一个不准确的值。
0.3转换成二进制 0.3 * 2 = 0.6不大于1, 二进制输入0, 继续对0.6 * 2 = 1.2,大于1,二进制为01, 继续对0。2处理,会发现永远都有小数部分,陷入无限循环。
toFixed精度问题
四舍五入是按位比较,0舍1入, 有可能1.335.toFixed(2) 不等于1.34 而是1.33
解决方案
解决就是将值能够正常的在内存中保存。
- 将小数相加的结果toFixed,保留几位小数,但是也有精度问题,常见的是保留3位小数,然后用正则匹配出两位小数。
- 将小数扩大成整数,然后除,前提是知道最多多少位,而且扩大成整数后不会超出最大长度。
- 采用自定义的方式计算
双精度64位是啥
就是用64位空间表示一个整数或者小数,头一位表示符号位,中间11位是指数E,后面52位是尾数位M。
E = -1 ^ 1 * M * 2 ^ E 十进制5表示成二进制是101 也是 1.01 * 2^2 表示成 -1 * 1.01(M) * 2 ^ 2
0.3表示成二进制是 0.01000100010001。。。。 表示成E = 1.000011111 ^ 2 ^ -2
