素材巴巴 > 程序开发 >

js加减乘除运算,小数精度丢失

程序开发 2023-09-08 12:33:08

一、出现浮点数失精的原因

小数失精度问题的原因是数字计算时,要先转成二进制再进行计算,计算完后再转成IEEE 754 浮点数。
有的小数再转二进制时会出现无限循环的情况,最后计算完再转回来就会导致精度丢失。

例:0.1转二进制的过程,整数部分为二进制数据,出现了死循环。

小数x2的结果整数部分0.10.200.20.400.40.800.81.610.61.210.20.40………

二、常见加减乘除做法

1、加法

/*** 加法运算,避免数据相加小数点后产生多位数和计算精度损失。* @param num1 加数1* @param num2 加数2*/
 function numAdd(num1, num2) {var baseNum, baseNum1, baseNum2;try {baseNum1 = num1.toString().split(".")[1].length;} catch (e) {baseNum1 = 0;}try {baseNum2 = num2.toString().split(".")[1].length;} catch (e) {baseNum2 = 0;}baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));return (num1 * baseNum + num2 * baseNum) / baseNum;
 };

2、减法

/*** 减法运算,避免数据相减小数点后产生多位数和计算精度损失。* @param num1 被减数* @param num2 减数 */
 function numSub(num1, num2) {var baseNum, baseNum1, baseNum2;var precision;// 精度try {baseNum1 = num1.toString().split(".")[1].length;} catch (e) {baseNum1 = 0;}try {baseNum2 = num2.toString().split(".")[1].length;} catch (e) {baseNum2 = 0;}baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));precision = (baseNum1 >= baseNum2) ? baseNum1 : baseNum2;return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);
 };

3、乘法

/*** 乘法运算,避免数据相乘小数点后产生多位数和计算精度损失。* @param num1 被乘数* @param num2 乘数 */
 function numMulti(num1, num2) {var baseNum = 0;try {baseNum += num1.toString().split(".")[1].length;} catch (e) {}try {baseNum += num2.toString().split(".")[1].length;} catch (e) {}return Number(num1.toString().replace(".", "")) * Number(num2.toString().replace(".", "")) / Math.pow(10, baseNum);
 };

4、除法

/*** 除法运算,避免数据相除小数点后产生多位数和计算精度损失。* @param num1 被除数* @param num2 除数 */
 function numDiv(num1, num2) {var baseNum1 = 0, baseNum2 = 0;var baseNum3, baseNum4;try {baseNum1 = num1.toString().split(".")[1].length;} catch (e) {baseNum1 = 0;}try {baseNum2 = num2.toString().split(".")[1].length;} catch (e) {baseNum2 = 0;}/*with (Math) {baseNum3 = Number(num1.toString().replace(".", ""));baseNum4 = Number(num2.toString().replace(".", ""));return (baseNum3 / baseNum4) * pow(10, baseNum2 - baseNum1);}*/baseNum3 = Number(num1.toString().replace(".", ""));baseNum4 = Number(num2.toString().replace(".", ""));if( (baseNum2 - baseNum1) < 0){return (baseNum3 / baseNum4) / Math.pow(10, baseNum1 - baseNum2)}return (baseNum3 / baseNum4) * Math.pow(10, baseNum2 - baseNum1);};
 

三、精度的另一种解决方案

parseFloat((0.1 + 0.2).toFixed(10))
 

原理:小数部分最多有17位,当出现失精的情况下,往往中间都是0,而最后一位是数字
在这里插入图片描述
截取小数点后十位,得到这样的结果:
在这里插入图片描述
最后转成浮点数,即想要的结果
在这里插入图片描述


标签:

素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。