瀏覽代碼

修改四舍五入,有效位数降低到15位

JimiZhang 7 年之前
父節點
當前提交
3e7eea7c3e
共有 1 個文件被更改,包括 10 次插入9 次删除
  1. 10 9
      public/web/scMathUtil.js

+ 10 - 9
public/web/scMathUtil.js

@@ -5,6 +5,12 @@
  *
  * zhangyin 2018-02-28
  * 采用重复一次四舍五入解决浮点精度误差后,10000次roundTo的时间为94毫秒。
+ *
+ * zhangyin 2018-04-28
+ * 因为js中的浮点数本身就有误差,经过运算后误差被放大,用加尾数的方式也不能消除。所以必须采用另一种思路。
+ * 考虑误差会被放大,因此放弃一位有效位数来消除误差,二进制有效位数50位,十进制有效位数15位。
+ * 原重复四舍五入的方法有缺陷,放弃。
+ * 10000次roundTo时间恢复到47毫秒
  */
 
 let scMathUtil = {
@@ -68,7 +74,8 @@ let scMathUtil = {
         let sResult2 = '';
         if (fNum > 0){
             // 双精度浮点数,尾数总长52位,因为第一位总是1,存储时已经被隐藏,所以有效位数为53位
-            const floatLength = 53;
+            // 由于js未对浮点数做优化,所以在有运算的情况下,误差会被放大,因此放弃一位有效位数来消除误差,二进制有效位数50位,十进制有效位数15位
+            const floatLength = 50;
 
             let iLength;
             // js的bug,浮点数直接取小数可能不能获得精确值,只有转成字符串,截取字符串中的小数段
@@ -155,16 +162,10 @@ let scMathUtil = {
         };
         return result;
     },
-    reRoundTo: function(num, digit){
-        let me = this;
-        return me.innerRoundTo(me.binToFloat(me.incMantissa(me.floatToBin(num))), digit);
-    },
-    // zhangyin 2018-02-28
-    // 经过运算后的浮点数,误差可能更大,加尾数也不能消除。目前采用笨办法,将有效位数加一位再四舍五入一次,以消除浮点误差。
-    // 此办法效率较低,没有别的更好办法时暂时用着
+
     roundTo: function(num, digit){
         let me = this;
-        return me.reRoundTo(me.reRoundTo(num, digit - 1), digit);
+        return me.innerRoundTo(me.binToFloat(me.incMantissa(me.floatToBin(num))), digit);
     },
     isNumber : function (obj) {
         return obj === +obj;