Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

解释一下在js里,0.1+0.2为什么等于0.30000000000000004,如何通过代码解决这个问题? #27

Open
airuikun opened this issue May 12, 2019 · 10 comments

Comments

@airuikun
Copy link
Owner

airuikun commented May 12, 2019

第二问我给个简单的思路吧:将浮点数转换为整数来进行计算。

答案不唯一,欢迎提供更好的idea

@fairyly
Copy link

fairyly commented May 13, 2019

原因:

  • 不仅 JavaScript,所有遵循 IEEE 754 规范的语言都是如此;
  • 在JavaScript中,所有的Number都是以64-bit的双精度浮点数存储的;
  • 双精度的浮点数在这64位上划分为3段,而这3段也就确定了一个浮点数的值,64bit的划分是“1-11-52”的模式,具体来说:
    • 1.就是1位最高位(最左边那一位)表示符号位,0表示正,1表示负;
    • 2.11位表示指数部分;
    • 3.52位表示尾数部分,也就是有效域部分

解决方案:

参考:

@lylwanan
Copy link

lylwanan commented May 13, 2019

function getMax() {
    var args = Array.prototype.slice.call(arguments, 0);

    return Math.max.apply(null, args.map(item => {
        var arr = item.toString().split('.');
        return arr.length > 1 ? arr[1].length : 0;
    }));
}

function add() {
    var args = Array.prototype.slice.call(arguments, 0);
    var max = getMax.apply(null, args);
	
    return args.reduce((sum, cur) => sum + cur * max * 10, 0) / 10 * max;
}

// 使用了题主的思路,我个人思路是大数计算
console.log(add(0.1, 0.2));

@ghost
Copy link

ghost commented May 13, 2019

Math.round((0.1+0.2)*100)/100

@shenyanggg
Copy link

1.取整
2.根据业务避免这样的代码

@nelsonkuang
Copy link

nelsonkuang commented May 13, 2019

来个全能版

      function add() {
        const args = [...arguments]
        const maxLen = Math.max.apply(
          null,
          args.map(item => {
            const str = String(item).split('.')[1]
            return str ? str.length : 0
          })
        )
        return (
          args.reduce((sum, cur) => sum + cur * 10 ** maxLen, 0) / 10 ** maxLen
        )
      }
      console.log(add(0.1, 0.2)) // => 0.3
      console.log(add(10, 11)) // => 21
      console.log(add(0.001, 0.003)) // => 0.004
      console.log(add(0.001, 0.003, 0.005)) // => 0.009
      console.log(add(0.001)) // => 0.001

@ghost
Copy link

ghost commented May 13, 2019 via email

@zjians
Copy link

zjians commented May 30, 2019

js中比较浮点数相等应该使用js提供的最小精度 EPSILON :
差值小于最小精度就是相等!
Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON

@webkonglong
Copy link

这个转化整数就能处理,难得是和number有关的是‘1212121212121212121212121212121’ + '12312312312312312312312312321312312312' = ? 答案要求是一个字符串,不要是科学计数法。

@ghrace
Copy link

ghrace commented Jun 26, 2019

parseFloat((0.1 + 0.2).toFixed(10))

@sanmuw
Copy link

sanmuw commented May 21, 2020

function tofixedNum(num) {
let n=0
numarr.forEach((item,index) => {
if(item.toString().includes('.')) {

   let tem = num.toString().split('.')[1].length
   if (tem>n) {
     n = tem
 }

}
})
return n;
}
((.1+.2).toFixed(tofixedNum([.1,.2])))*1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants