前言
对于现在技术社区的现状的,我分析用户画像 觉得大部分的用户更多的是喜欢短频快的节奏文章,所以故尝试用最短时间挖掘简单的面试题,将背后的知识整理分享给大家,喜欢在后续的面试过程中,可以对你有帮助,如果刚好是自己的知识盲区不妨帮忙点赞支持一下
背景
0.3 - 0.1 // 0.19999999
0.2 + 0.1 // 0.30000000000000004
复制代码
在Javascript
中 小数数相加或者相减,会出现精度问题,这种问题总结来说是属于 Javascript
中二进制相关的基础知识。本文介绍的是如何实现方法来解决这种的问题,下面将列举几种解决方法,欢迎补充纠正,谢谢
解法一
我们熟识拿来主义中,最简单直接的解决办法,是用第三方的已经实现好的功能,这里使用的是bignumber.js
import BigNumber from "bignumber.js";
x = new BigNumber(0.3)
x.minus(0.1) // "0.2"
x // "0.3"
x.plus(0.2)
x // "0.3"
复制代码
解法二
万一面试官追问想要让你手写解法的话,解题的思路是,将小数变成整数进行相加,然后再将它变回小数输出,这里需要注意的点是,substr
获取到的下标 需要往前 +1 位
加法&减法
// 获取小数点位数是有哪些
const getDecimalPlaces = num => {
// 如果是整数的情况
if (Math.floor(num) === num) {
return 0
}
const str = String(num);
const pointIdx = str.indexOf('.')
const len = str.substr(pointIdx + 1).length;
return len;
}
// 数字加法运算
const add = (num1, num2) => {
if (!Number.isNaN(num1) && !Number.isNaN(num2)) return new TypeError('请传入数字类型')
let result = 0;
const num1Len = getDecimalPlaces(num1); // 数字1长度
const num2Len = getDecimalPlaces(num2); // 数字2长度
const maxLen = num1Len > num2Len ? num1Len : num2Len; // 取两者之间比较长的一位
const maxTimes = Math.pow(10, maxLen); // 最大 10 的倍数
result = (num1 * maxTimes + num2 * maxTimes) / maxTimes;
return result;
}
// 数字减法运算
const minus = (num1, num2) => {
if (!Number.isNaN(num1) && !Number.isNaN(num2)) return new TypeError('请传入数字类型')
let result = 0;
const num1Len = getDecimalPlaces(num1); // 数字1长度
const num2Len = getDecimalPlaces(num2); // 数字2长度
const maxLen = num1Len > num2Len ? num1Len : num2Len; // 取两者之间比较长的一位
const maxTimes = Math.pow(10, maxLen); // 需要补多少 0
result = (num1 * maxTimes - num2 * maxTimes) / maxTimes; // 减价其实只是数字操作符号差异
return result;
}
复制代码
解法三
欢迎在评论区补充…
核心原理
简单一句话:Javascript
的浮点数存储 遵循 IEEE-754
标准的实现,这个标准在存储数字的时候,因为存储逻辑关系导致的出现结尾几位的精度问题,详细可以对比下图
尾数位存储的话,相加的时候就会出现精度问题,
尾数为不存储的话,相加相减是不会出现精度问题的,例如 0.25,0.125,0.5…等等
小结
这篇文章到这里就结束了,水平有限难免有纰漏,欢迎纠错。最后希望帮忙点点赞,这对我创作是无比的肯定和动力。希望可以帮到你
文章参考
硬核基础二进制篇(一)0.1 + 0.2 != 0.3 和 IEEE-754 标准
Number API
dev Tools
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END