js浮点数问题

222 阅读1分钟
JS 0.1 + 0.2 != 0.3

为什么0.1+0.2不等于0.3

babbage.cs.qc.cuny.edu/IEEE-754.ol…

  • 浮点数在计算机底层的时候,存储的二进制数可能被舍弃掉一部分[因为最多只有64位],所以本身和原来的十进制就不一样了所以出现了精度的问题
  • 当计算机底层用0.1+0.2相加是用二进制数相加本来就不够精确然后就更加不精确了
  • 计算机底层返回给浏览器64位的二进制 而浏览器就识别小数点后面17位就会把后面的省略掉

例如:0.1+0.2 = 0.3000000000004(后面的就是省略的部分)

​ 0.1+ 0.3 = 0.4000000000000(后面的就是省略的部分) =>简写成0.4

十进制转换为二进制

一般处理

/*
	1.简单处理
*/
var str = 10;
console.log(str.toString(2));

手写进制转换

//进制转换
~function (){
    function transitionScale(scale){
        // 短除法
        let num = Math.floor(this/scale),
            remainder = this % scale,
            remainderAry = [];
            remainderAry.unshift(remainder);
        while(num){
            remainder = num % scale;
            num = Math.floor(num/scale);
            remainderAry.unshift(remainder);
        }
        return Number(remainderAry.join(""))
    }

    ['transitionScale'].forEach(v => {
        Number.prototype[v] = eval(v);
    })
}()

var num = 10;
console.log(num.transitionScale(2)); //=> 1010
精确浮点数计算

浮点数不够精确问题是所有高级语言的通病

所以在公司进行浮点数操作都需要进行浮点数精确

/*
	偷懒情况下,公司都使用toFixed
*/
var num = 0.3004;
console.log(num.toFixed(2));

手写浮点数计算

// 手写浮点数计算
~function(){
    //小数点长度比较返回最长长度
    function getMaxdecimals(args){
        let maxlength = -1
        args.forEach((v,i) => {
            let itemlen  = String(v).split(".")[1].length
            maxlength < itemlen ? maxlength = itemlen : null;
        })
        return maxlength
    }

    function preciseFloat(type){
        // 记住最长的[0.5003,0.1] 返回 4
        let maxlen = getMaxdecimals(this);
        let newAry = this.map((v) => {
            return v*Math.pow(10,maxlen);
        })
        let sum = newAry.reduce((pre,next) => {
            return eval(pre +type+ next)
        })
        let result;
        type === "*" ? result = sum/Math.pow(10,2 * maxlen):
        type === "/" ? result = sum:result = sum/Math.pow(10,maxlen)
        return result;
    }

    ['preciseFloat'].forEach((v,i) => {
        Array.prototype[v] = eval(v);
    })
}()

let a = 109.122,
    b = 10.122;
console.log([a,b].preciseFloat("+"))