小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
前言
在使用浮点计算的时候明明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()
。如果该参数是一个非整数值,将会向下舍入到最接近的整数。