javascript 浮点计算

这几天在进行浮点运算时候遇到一个问题,toFixd()给出的四舍五入值“几率性”的出现错误!

我们举个列子 :

  alert(0.1+0.2); //输出 0.30000000000000004

  alert(Number(1.005).toFixed(2));  //输出 1.00

  alert(Number(1.006).toFixed(2));  //输出 1.01

从上面我们可以看到,只有最后一个是正确的。为什么会这样呢?

由于计算机是用二进制来存储和处理数字,不能精确表示浮点数,而js中没有相应的封装类来处理浮点数运算,直接计算会导致运算精度丢失。

 0.1在js里面就需要被表示成 1/16+1/32+.......转换成二进制就是0.00011001100110011无限循环

 0.5在js里面就可以直接表示成1/2  转换成二进制就是0.01 

 所几率性出错就可以被解释了,可以被2的负多少次方精确表示出来的是不会丢失精度。如果不能被表示则会丢失精度!

下面是从网上找到的一个覆盖toFixed()的js代码,在这里和大家分享下:

 

  1 <script type="text/javascript">
  2 /** 
  3  * 左补齐字符串 
  4  * @param nSize 要补齐的长度 
  5  * @param ch 要补齐的字符 
  6  * @return 
  7  */
  8 String.prototype.padLeft = function (nSize, ch) {
  9     var len = 0;
 10     var s = this ? this : "";
 11     ch = ch ? ch : '0'; // 默认补0  
 12     len = s.length;
 13     while (len < nSize) {
 14         s = ch + s;
 15         len++;
 16     }
 17     return s;
 18 }
 19 
 20 /** 
 21  * 右补齐字符串 
 22  * @param nSize 要补齐的长度 
 23  * @param ch 要补齐的字符 
 24  * @return 
 25  */
 26 String.prototype.padRight = function (nSize, ch) {
 27     var len = 0;
 28     var s = this ? this : "";
 29     ch = ch ? ch : '0'; // 默认补0  
 30     len = s.length;
 31     while (len < nSize) {
 32         s = s + ch;
 33         len++;
 34     }
 35     return s;
 36 }
 37 /** 
 38  * 左移小数点位置(用于数学计算,相当于除以Math.pow(10,scale)) 
 39  * @param scale 要移位的刻度 
 40  * @return 
 41  */
 42 String.prototype.movePointLeft = function (scale) {
 43     var s, s1, s2, ch, ps, sign;
 44     ch = '.';
 45     sign = '';
 46     s = this ? this : "";
 47     if (scale <= 0) return s;
 48     ps = s.split('.');
 49     s1 = ps[0] ? ps[0] : "";
 50     s2 = ps[1] ? ps[1] : "";
 51     if (s1.slice(0, 1) == '-') {
 52         s1 = s1.slice(1);
 53         sign = '-';
 54     }
 55     if (s1.length <= scale) {
 56         ch = "0.";
 57         s1 = s1.padLeft(scale);
 58     }
 59     return sign + s1.slice(0, -scale) + ch + s1.slice(-scale) + s2;
 60 }
 61 /** 
 62  * 右移小数点位置(用于数学计算,相当于乘以Math.pow(10,scale)) 
 63  * @param scale 要移位的刻度 
 64  * @return 
 65  */
 66 String.prototype.movePointRight = function (scale) {
 67     var s, s1, s2, ch, ps;
 68     ch = '.';
 69     s = this ? this : "";
 70 
 71     if (scale <= 0) return s;
 72     ps = s.split('.');
 73     s1 = ps[0] ? ps[0] : "";
 74     s2 = ps[1] ? ps[1] : "";
 75     if (s2.length <= scale) {
 76         ch = '';
 77         s2 = s2.padRight(scale);
 78     }
 79     return s1 + s2.slice(0, scale) + ch + s2.slice(scale, s2.length);
 80 }
 81 /** 
 82  * 移动小数点位置(用于数学计算,相当于(乘以/除以)Math.pow(10,scale)) 
 83  * @param scale 要移位的刻度(正数表示向右移;负数表示向左移动;0返回原值) 
 84  * @return 
 85  */
 86 String.prototype.movePoint = function (scale) {
 87     if (scale >= 0)
 88         return this.movePointRight(scale);
 89     else
 90         return this.movePointLeft(-scale);
 91 }
 92 
 93 Number.prototype.toFixed = function (scale) {
 94     var s, s1, s2, start;
 95     s1 = this + "";
 96     start = s1.indexOf(".");
 97     s = s1.movePoint(scale);
 98     if (start >= 0) {
 99         s2 = Number(s1.substr(start + scale + 1, 1));
100         if (s2 >= 5 && this >= 0 || s2 < 5 && this < 0) {
101             s = Math.ceil(s);
102         } else {
103             s = Math.floor(s);
104         }
105     }
106     return s.toString().movePoint(-scale);
107 }
108 </script>

 

加入上述代码后

alert(Number(1.005).toFixed(2)); //输出 1.01

如果要进行浮点计算 就要使用movePoint方法进行升值操作后再降值得出精确结果!

 

转载于:https://www.cnblogs.com/x-radish/archive/2013/03/26/2983155.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值