分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

Js浮点运算存在精度问题

发布时间:2023-09-06 01:27责任编辑:蔡小小关键词:暂无标签

     记得在某一次项目中,运用js进行一系列算数运算,计算中会存在浮点类型,就单纯的进行了计算,最后在测试过程中,主管在核对数据的时候发现计算的结果是有问题的,于是就很纳闷,在网上搜索找到了答案  ,http://www.css88.com/archives/7340

      原因:计算过程中的十进制的数会先转换二进制,进行计算,然后将结果在转换为十进制(往往有些浮点类型数值转换为二进制是无穷的),所以往往也会导致出现精度问题

那么如何解决呢?

网上提供的方案如下:

 ?1 /** ?2 ?** 加法函数,用来得到精确的加法结果 ?3 ?** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。 ?4 ?** 调用:accAdd(arg1,arg2) ?5 ?** 返回值:arg1加上arg2的精确结果 ?6 ?**/ ?7 function accAdd(arg1, arg2) { ?8 ????var r1, r2, m, c; ?9 ????try { 10 ????????r1 = arg1.toString().split(".")[1].length; 11 ????} 12 ????catch (e) { 13 ????????r1 = 0; 14 ????} 15 ????try { 16 ????????r2 = arg2.toString().split(".")[1].length; 17 ????} 18 ????catch (e) { 19 ????????r2 = 0; 20 ????} 21 ????c = Math.abs(r1 - r2); 22 ????m = Math.pow(10, Math.max(r1, r2)); 23 ????if (c > 0) { 24 ????????var cm = Math.pow(10, c); 25 ????????if (r1 > r2) { 26 ????????????arg1 = Number(arg1.toString().replace(".", "")); 27 ????????????arg2 = Number(arg2.toString().replace(".", "")) * cm; 28 ????????} else { 29 ????????????arg1 = Number(arg1.toString().replace(".", "")) * cm; 30 ????????????arg2 = Number(arg2.toString().replace(".", "")); 31 ????????} 32 ????} else { 33 ????????arg1 = Number(arg1.toString().replace(".", "")); 34 ????????arg2 = Number(arg2.toString().replace(".", "")); 35 ????} 36 ????return (arg1 + arg2) / m; 37 } 38 ??39 //给Number类型增加一个add方法,调用起来更加方便。 40 Number.prototype.add = function (arg) { 41 ????return accAdd(arg, this); 42 }; 43 ?44 /** 45 ?** 减法函数,用来得到精确的减法结果 46 ?** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。 47 ?** 调用:accSub(arg1,arg2) 48 ?** 返回值:arg1加上arg2的精确结果 49 ?**/ 50 function accSub(arg1, arg2) { 51 ????var r1, r2, m, n; 52 ????try { 53 ????????r1 = arg1.toString().split(".")[1].length; 54 ????} 55 ????catch (e) { 56 ????????r1 = 0; 57 ????} 58 ????try { 59 ????????r2 = arg2.toString().split(".")[1].length; 60 ????} 61 ????catch (e) { 62 ????????r2 = 0; 63 ????} 64 ????m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度 65 ????n = (r1 >= r2) ? r1 : r2; 66 ????return ((arg1 * m - arg2 * m) / m).toFixed(n); 67 } 68 ??69 // 给Number类型增加一个mul方法,调用起来更加方便。 70 Number.prototype.sub = function (arg) { 71 ????return accMul(arg, this); 72 }; 73 ?74 ?75 /** 76 ?** 乘法函数,用来得到精确的乘法结果 77 ?** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。 78 ?** 调用:accMul(arg1,arg2) 79 ?** 返回值:arg1乘以 arg2的精确结果 80 ?**/ 81 function accMul(arg1, arg2) { 82 ????var m = 0, s1 = arg1.toString(), s2 = arg2.toString(); 83 ????try { 84 ????????m += s1.split(".")[1].length; 85 ????} 86 ????catch (e) { 87 ????} 88 ????try { 89 ????????m += s2.split(".")[1].length; 90 ????} 91 ????catch (e) { 92 ????} 93 ????return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m); 94 } 95 ??96 // 给Number类型增加一个mul方法,调用起来更加方便。 97 Number.prototype.mul = function (arg) { 98 ????return accMul(arg, this); 99 };100 101 102 /** 103 ?** 除法函数,用来得到精确的除法结果104 ?** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。105 ?** 调用:accDiv(arg1,arg2)106 ?** 返回值:arg1除以arg2的精确结果107 ?**/108 function accDiv(arg1, arg2) {109 ????var t1 = 0, t2 = 0, r1, r2;110 ????try {111 ????????t1 = arg1.toString().split(".")[1].length;112 ????}113 ????catch (e) {114 ????}115 ????try {116 ????????t2 = arg2.toString().split(".")[1].length;117 ????}118 ????catch (e) {119 ????}120 ????with (Math) {121 ????????r1 = Number(arg1.toString().replace(".", ""));122 ????????r2 = Number(arg2.toString().replace(".", ""));123 ????????return (r1 / r2) * pow(10, t2 - t1);124 ????}125 }126 ?127 //给Number类型增加一个div方法,调用起来更加方便。128 Number.prototype.div = function (arg) {129 ????return accDiv(this, arg);130 };

Js浮点运算存在精度问题

原文地址:http://www.cnblogs.com/ZQWelcomeIndex/p/7896883.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved