产生精度丢失的原因:计算机存储的位数是有限的
JS中所有值都是以2进制在计算机底层进行存储的(浮点数转为二进制,可能出现无限循环的情况]+ 在计算机底层存储的时候,最多存储64位舍弃了一些值(计算机是几位最大存储位就是多少位),值本身就失去了精准度]
解决方案: 1、 toFixed保留小数点后面N位,他自己会四舍五入
2、 扩大系数法
3、使用三方库如Math.js 、decimal.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// JS中有关于小数(浮点数)的计算会出现精准度丢失的问题
// JS中所有值都是以2进制在计算机底层进行存储的(浮点数转为二进制,可能出现无限循环的情况]+ 在计算机底层存储的时候,最多存储64位舍弃了一些值(计算机是几位最大存储位就是多少位),值本身就失去了精准度]// 浮点数计算的解决方案:
// 1、 toFixed保留小数点后面N位,他自己会四舍五入
// function retention(a, b) {
// let a1 = String(a).split('.');
// let b1 = String(b).split('.');
// // console.log(a1,b1);
// let z = a1[1].length > b1[1].length ? a1[1].length : b1[1].length;
// // console.log(z);
// return (a + b).toFixed(z)
// }
// console.log(retention(0.1, 0.32345));
// console.log(retention(0.1, -0.32345));
// 2、 扩大系数法
// function big(a,b){
// let a1 = String(a).split('.');
// let b1 = String(b).split('.');
// // console.log(a1,b1);
// let z = a1[1].length > b1[1].length ? a1[1].length : b1[1].length;
// return (a*z+b*z)/z
// }
// console.log( big(1.23435,0.2345));
// console.log( big(1.23435,-0.2345));
// 3、三方类库 如Math.js 原理跟扩大系数法一样
// 完善 不止两个数的相加减
function qiuMax(...arg) {
// console.log(arguments);//arguments是一个类数组不能直接用数组的方法处理
let max = 0;
for (let i = 0; i < arguments.length; i++) {
max = max > String(arguments[i]).split('.')[1].length ? max : String(arguments[i]).split('.')[1].length
// arr.push(String(arguments[i]).split('.')[1].length)// 此路不通,要重新处理数组取最大值,太麻烦了
}
return max
}
function retention1(...arg) {
let max=qiuMax(...arg);
// toFixed 两者用一个就行
let sum = 0
for (let i = 0; i < arguments.length; i++) {
sum = (sum*1 + arguments[i]*1).toFixed(max);
return sum
}
// 扩大系数
// let p=0;
// for (let i = 0; i < arguments.length; i++) {
// p=(p+arguments[i]*Math.pow(10,max));
// }
// return p/Math.pow(10,max)
}
console.log( retention1(0.1, 0.1, 0.12, 0.1));
</script>
</body>
</html>
最后的完善版其实也不算很好,水平有限,将就看吧!