娱乐-JS怎么算0.1+0.2?

326 阅读2分钟

0.引言

打开控制台输入 0.1 + 0.2 得到 0.30000000000000004 为什么会这样,问题很大!

0.1 + 0.2
// 0.30000000000000004

image.png

1.为什么?

如下图在十进制中,小数点前面分别表示个十百千万... 小数点后面分别表示1/10、1/100、1/1000...这里没有任何问题

image.png

但是计算机是二进制的,每一位只能是0或1,并且逢二进一,则每一位数字表示的是2的幂次

如下图,小数点前面分别表示24(2的平方)8(2的立方)16(2的四次方)...

小数点后面则只能表示1/2(2的-1次方)1/4(2的-2次方)1/8(2的-3次方)... 在二进制中,小数点后的数不存在1/10,所以不能和十进制一样精确表示浮点数

image.png

2.娱乐-如何精确计算浮点数

这是我突然想到的话题,没有仔细研究过如何解决这个问题,以下方法只是娱乐,

有兴趣研究这个问题的可以参考

math.js是专门用来解决JS计算精度问题的类库
官网地址: mathjs.org/index.html
gitHub: github.com/josdejong/m…

  • 1.先找出两个浮点数后面最长的位数L
  • 2.两个浮点数同时乘上10的L次方S缩放到最小整数,这样就只有整数运算了
  • 3.先执行两数相加,再将结果除以S
  • 4.返回结果
function floatAdd(a, b) {
    // 先找出小数点后位数最长的长度
    const aLen = a >> 0 === a ? 0 : a.toString().split(".")[1].length;
    const bLen = b >> 0 === b ? 0 : b.toString().split(".")[1].length;
    const L = aLen > bLen ? aLen : bLen;
    
    // 同时缩放到最小整数位后相加
    const S = Math.pow(10, L);
    const vt = a * S + b * S;
    
    // 返回结果再缩放回去
    return vt / S;
}

试几个例子,目前ok

image.png