balalala 发表于 2023-3-3 18:47:03

14-spreadjs精度丢失后续问题(SJS-17944)

本帖最后由 Richard.Ma 于 2023-4-20 13:56 编辑


sheet3 H列显示‘N’就标识精度丢失,显示‘Y’表示精度没有丢失。添加上`GC.Spread.CalcEngine.Functions.CALC_PRECISION=16`这句代码,精度丢失问题解决。

但是B表使用公式获取A表的值填充出现问题。


Richard.Ma 发表于 2023-3-6 10:31:40

此计算问题在新版本已经修复,建议你升级到V16新版本可以直接解决。不需要设置CALC_PRECISION,sheet3的计算结果也是正常的,你可以在在线示例中测试一下
https://demo.grapecity.com.cn/SpreadJS/WebDesigner/index.html

老版本目前没有什么好办法。

balalala 发表于 2023-3-6 15:05:34

Richard.Ma 发表于 2023-3-6 10:31
此计算问题在新版本已经修复,建议你升级到V16新版本可以直接解决。不需要设置CALC_PRECISION,sheet3的计 ...

16版本好像没有完全解决。
把sheet3的公式和数据放到官网在线示例上,H列会存在N的情况。要不您试一下。

Richard.Ma 发表于 2023-3-6 17:13:02

我是直接通过在线编辑器导入的你的test.xlsx文件,并没有发现你说的问题




balalala 发表于 2023-3-6 18:06:23

Richard.Ma 发表于 2023-3-6 17:13
我是直接通过在线编辑器导入的你的test.xlsx文件,并没有发现你说的问题

直接导入没有问题。但是对数据进行变更或复制到一个新表sheet4中,精度就不准了。
复现方法:下图中的红框内先调整为别的值,再调整为=1/3,就不再是Y了。
可能是导入方法进行了别的额外操作。

balalala 发表于 2023-3-6 18:08:01

Richard.Ma 发表于 2023-3-7 14:35:22

问题重现出来了,这个SUMIF公式计算结果确实有问题。我先把这个作为bug提给研发。帖子暂时保留处理

理论上来说设置精度不应该影响SUMIF的计算结果,通过getValue获取到的SUMIF条件中的两个单元格的值也确实都是0.0468。

Richard.Ma 发表于 2023-4-24 16:23:06

你好,此问题属于产品功能限制,根本原因是 javascript 原生计算精度问题。不管我们如何调整我们的calc engine精度逻辑,最终还是基于原生的计算操作。

作为解决方法,建议可以尝试覆盖原生的toPrecision函数,进行四舍五入,但是这样一来,如果一个值不是因为精度问题,原生就是这样的话,也会被四舍五入。建议谨慎评估后使用

var nativeToPrecisionFn = Number.prototype.toPrecision;
Number.prototype.toPrecision = function () {
    var value = this.valueOf();
    if (true) {
      var valuestr = nativeToPrecisionFn.apply(this, arguments);
      
      var decimalPart = valuestr.split('.'), integerPart = valuestr.split('.');
      var zeroMatchCount=0,nineMatchCount=0;
      var zeroMatchCount = decimalPart.match(/(0+)$/)?decimalPart.match(/(0+)$/).length:0;
      var nineMatchCount = decimalPart.match(/(9+)$/)?decimalPart.match(/(9+)$/).length:0;
      if (decimalPart && (zeroMatchCount > 7 || nineMatchCount > 7)) {
            
            var scale=Math.pow(10,(decimalPart.length-Math.max(zeroMatchCount,nineMatchCount)));
            console.log(decimalPart.length,Math.max(zeroMatchCount,nineMatchCount),scale);
            decimalPart.length-Math.max(zeroMatchCount,nineMatchCount)
            return Math.round(value*scale)/scale + "";
      }
      
      return valuestr;
    }

    return nativeToPrecisionFn.apply(this, arguments);
}

页: [1]
查看完整版本: 14-spreadjs精度丢失后续问题(SJS-17944)