你用js计算浮点数了没?

436 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

在使用浮点计算的时候明明1.56+0.07=1.63,小学生都会算的,可是计算机为什么算出来很长一段数字呢? 因为JavaScript 里的数字是采用 IEEE 754 标准的 64 位双精度浮点数。该规范定义了浮点数的格式。

有这样一个实现浮点计算的加法的面试题

function add(a, b) {
  // TODO
}
 
console.log(add(0.1, 0.2)) // 0.3

你要怎么去实现呢?

处理方法

重新写了一些浮点运算的函数或直接扩大倍数运算。

下面以扩大倍数运算举例子:【原理把小数变成整数,然后做运算处理,再除以放大倍数】

方案一

这可能是我们一般人的思路,自行去乘,自行去除

function add(a, b) {
  // TODO
  //要放大的倍数
  const r = Array.from(arguments).reduce((prev, cur, index) => {
    const curLen = `${cur}`.split(".")[1].length;
    return curLen > prev ? curLen : prev;
  }, 0);
  let mi = Math.pow(10, r);
  const result = a * mi + b * mi;
  return result / mi;
}

console.log(add(0.0001, 0.02)); // 0.3

方案二

Number.prototype.toPrecision(),今天看到这个属性,恍然大悟

function add(a, b) {
  // TODO
  //要放大的倍数
  const r = Array.from(arguments).reduce((prev, cur, index) => {
    const curLen = `${cur}`.split(".")[1].length;
    return curLen > prev ? curLen : prev;
  }, 0);
  const result = (a + b).toPrecision(r);
  return result;

过程是不是更简洁了些?

.toPrecision注意事项

以定点表示法或指数表示法表示的一个数值对象的字符串表示,四舍五入到 precision 参数指定的显示数字位数。查看 Number.prototype.toFixed() 方法关于四舍五入的讨论,同样应用于 toPrecision 方法。

如果忽略 precision 参数,则该方法表现类似于 Number.prototype.toString()。如果该参数是一个非整数值,将会向下舍入到最接近的整数。