我是这样解决JavaScript加减乘除精度问题的最经典的例子就是why0.1+0.2!==0.3一句话,ECMAScript规范定义Number的类型要遵循IEEE754-2008中的64位浮点数规则。存在精度损失的问题!不过网上已经有很多专门的库可以解决这个问题。原生包加法/****加法函数,用于得到准确的加法结果**注意:javascript的加法结果会有误差,两个浮点数相加时会更加明显。此函数返回更准确的加法结果。**调用:accAdd(arg1,arg2)**返回值:arg1加上arg2的精确结果**/functionaccAdd(arg1,arg2){letr1,r2,mtry{r1=arg1.toString().split('.')[1].length}catch(e){r1=0}try{r2=arg2.toString().split('.')[1].length}catch(e){r2=0}m=Math.pow(10,Math.max(r1,r2))return(arg1*m+arg2*m)/m}subtraction/****减法函数,用于得到准确的减法结果**说明:javascript会有是减法结果的错误,当两个浮点数相减时会更加明显。此函数返回更准确的减法结果。**调用:accSub(arg1,arg2)**返回值:arg1加上arg2的精确结果**/functionaccSub(arg1,arg2){varr1,r2,m,n;try{r1=arg1.toString()。split(".")[1].length;}catch(e){r1=0;}try{r2=arg2.toString().split(".")[1].length;}catch(e){r2=0;}m=Math.pow(10,Math.max(r1,r2));//lastmodifybydeeka//动态控制精度长度n=r1>=r2?r1:r2;return((arg1*m-arg2*m)/m).toFixed(n);}multiply/****乘法函数,用于得到准确的乘法结果**注意:javascript的乘法结果会有错误,当两个浮点数相乘时会更明显。此函数返回更准确的乘法结果。**调用:accMul(arg1,arg2)**返回值:arg1乘以arg2的准确结果**/functionaccMul(arg1,arg2){letm=0lets1=arg1.toString()lets2=arg2.toString()try{m+=s1.split('.')[1]?s1.split('.')[1].length:''}catch(e){}try{m+=s2.split('.')[1]?s2.split('.')[1].length:''}catch(e){}return(Number(s1.replace('.',''))*Number(s2.replace('.','')))/Math.pow(10,m)}Division/****除法函数,用于得到准确的除法结果**注意:javascript除法结果会有误差,两个float之间会分点时更明显。此函数返回更准确的除法结果。**调用:accDiv(arg1,arg2)**返回值:arg1除以arg2的准确结果**/functionaccDiv(arg1,arg2){lett1=0lett2=0letr1letr2try{t1=arg1.toString().split('.')[1].length}catch(e){}try{t2=arg2.toString().split('.')[1].length}catch(e){}r1=Number(arg1.toString().replace('.',''))r2=Number(arg2.toString().replace('.',''))return(r1/r2)*Math.pow(10,t2-t1)}封装定义一个函数来调用加减乘除的方法。这样做的好处是加减乘除的方法都在同一个地方调用。假设某个方法后来发现这个库比较好用或者某个平台不兼容,算法不严谨。扩展新功能等,只需要维护这个功能即可,不需要考虑在项目中单独引用某个组件。因本次维修引起的新问题,不按本规范执行。exportconstcalcFn={add(){constarg=Array.from(arguments)returnarg.reduce((total,num)=>{returnaccAdd(total,num)})},sub(){constarg=Array.from(arguments)returnarg.reduce((total,num)=>{returnaccSub(total,num)})},mul(){constarg=Array.from(arguments)returnarg.reduce((total,num)=>{returnaccMul(total,num))})},divide(){constarg=Array.from(arguments)returnarg.reduce((total,num)=>{returnaccDiv(total,num)})}}big.js介绍:任意精度小数运算小型、快速、易于使用的库。特点:目前同类型最小包,无依赖,包大小3KB,兼容ECMAScript3+,可以说适用于所有浏览器。官网:GitHubhttps://github.com/MikeMcl/big.js/安装使用浏览器Node.jsnpminallbig.js使用x=newBig(0.1)y=newBig(0.2)z=newBig(0.3)x.plus(y).eq(z)//真正的算子运算函数跟随big。js目前支持算子操作函数。abs,取绝对值。cmp是compare的缩写,即比较函数。div,除法。eq,equal的缩写,即相等比较。gt,大于。gte,小于或等于,e表示等于。lt,小于。lte,小于或等于,e表示等于。减,减法。mod,取余数。加上,补充。战俘,权力。prec,按精度四舍五入,参数代表总位数。round,按精度取整,参数表示小数点后的位数。平方根,平方根。次,乘法。toExponential,转换为科学计数法,参数表示精度的位数。toFied,完成位数,参数表示小数点后的位数。toJSON和toString,转换为字符串。toPrecision,按照指定的有效位数显示,参数为有效位数。toNumber,转换为JavaScript中的number类型。valueOf,一个包含减号的字符串(如果为负,则为-0)。packageimportBigfrom'big.js'exportconstcalcFn={add(){constarg=Array.from(arguments)returnarg.reduce((total,num)=>{returnnewBig(total).plus(newBig(num))}).toString()*1},sub(){constarg=Array.from(arguments)returnarg.reduce((total,num)=>{returnnewBig(total).minus(newBig(num))}).toString()*1},mul(){constarg=Array.from(arguments)returnarg.reduce((total,num)=>{returnnewBig(total).times(newBig(num))}).toString()*1},divide(){constarg=Array.from(arguments)returnarg.reduce((total,num)=>{returnnewBig(total).div(newBig(num))}).toString()*1}}使用calcFn.add(0.1,0.2)!==0.3//falsebignnumber.js描述:任意精度十进制和非十进制运算的JavaScript库。特点:无依赖,包大小8KB,兼容ECMAScript3+可以说适用于所有浏览器。官网:GitHubhttps://github.com/MikeMcl/bignumber.js用法类似,如上。Decimal.js简介:为JavaScript提供小数类型的任意精度值。特点:无依赖,包大小12.6KB,兼容ECMAScript3+可以说适用于所有浏览器。官网:GitHubhttps://github.com/MikeMcl/decimal.js用法类似,如上。介绍Math.js:一个用Javascript编写的简单数学库,可能不再维护。特点:是一个广泛的JavaScript和Node.js数学库。它具有灵活的表达式解析器,支持符号计算,自带大量内置函数和常量,并提供了处理不同数据类型的集成解决方案,如数字、大数、复数、分数、单位和矩阵。功能强大且易于使用。官网:GitHub总结big.js适用于大多数十进制算术应用,因为NaN或Infinity不被接受为合法值。并且不支持其他基数中的值。如果项目中没有非十进制运算,这个很适合用,关键是包太小了。哈哈,还是觉得我自己做的轮子后面的库比较香。bignumber.js可能更适合金融应用,因为用户不需要担心精度丢失,除非他们使用涉及除法的操作。decimal.js可能更适合更科学的应用,因为它可以更有效地处理非常小或大的值。例如,它没有bignumber.js的限制,当一个小指数的值与一个大指数的值相加时,bignumber.js会尝试进行全精度运算,这可能导致运算不可行。如前所述,decimal.js还支持非整数幂,并增加了三角函数和exp、ln和log方法。这些添加使decimal.js明显大于bignumber.js。
