找回密码
 立即注册

QQ登录

只需一步,快速开始

balalala

注册会员

13

主题

50

帖子

139

积分

注册会员

积分
139
balalala
注册会员   /  发表于:2023-3-3 18:47  /   查看:2508  /  回复:7
本帖最后由 Richard.Ma 于 2023-4-20 13:56 编辑

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

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


demo.zip

3.11 MB, 下载次数: 207

7 个回复

倒序浏览
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于: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讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-3-6 17:13:02
地板
我是直接通过在线编辑器导入的你的test.xlsx文件,并没有发现你说的问题
image.png502583007.png
image.png142753295.png


回复 使用道具 举报
balalala
注册会员   /  发表于:2023-3-6 18:06:23
5#
Richard.Ma 发表于 2023-3-6 17:13
我是直接通过在线编辑器导入的你的test.xlsx文件,并没有发现你说的问题

直接导入没有问题。但是对数据进行变更或复制到一个新表sheet4中,精度就不准了。
复现方法:下图中的红框内先调整为别的值,再调整为=1/3,就不再是Y了。
可能是导入方法进行了别的额外操作。
回复 使用道具 举报
balalala
注册会员   /  发表于:2023-3-6 18:08:01
6#
image.png748965148.png image.png316988219.png
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-3-7 14:35:22
7#
问题重现出来了,这个SUMIF公式计算结果确实有问题。我先把这个作为bug提给研发。帖子暂时保留处理

理论上来说设置精度不应该影响SUMIF的计算结果,通过getValue获取到的SUMIF条件中的两个单元格的值也确实都是0.0468。
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-4-24 16:23:06
8#
你好,此问题属于产品功能限制,根本原因是 javascript 原生计算精度问题。不管我们如何调整我们的calc engine精度逻辑,最终还是基于原生的计算操作。

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

  1. var nativeToPrecisionFn = Number.prototype.toPrecision;
  2. Number.prototype.toPrecision = function () {
  3.     var value = this.valueOf();
  4.     if (true) {
  5.         var valuestr = nativeToPrecisionFn.apply(this, arguments);
  6.         
  7.         var decimalPart = valuestr.split('.')[1], integerPart = valuestr.split('.')[0];
  8.         var zeroMatchCount=0,nineMatchCount=0;
  9.         var zeroMatchCount = decimalPart.match(/(0+)$/)?decimalPart.match(/(0+)$/)[0].length:0;
  10.         var nineMatchCount = decimalPart.match(/(9+)$/)?decimalPart.match(/(9+)$/)[0].length:0;
  11.         if (decimalPart && (zeroMatchCount > 7 || nineMatchCount > 7)) {
  12.             
  13.             var scale=Math.pow(10,(decimalPart.length-Math.max(zeroMatchCount,nineMatchCount)));
  14.             console.log(decimalPart.length,Math.max(zeroMatchCount,nineMatchCount),scale);
  15.             decimalPart.length-Math.max(zeroMatchCount,nineMatchCount)
  16.             return Math.round(value*scale)/scale + "";
  17.         }
  18.         
  19.         return valuestr;
  20.     }

  21.     return nativeToPrecisionFn.apply(this, arguments);
  22. }
复制代码


回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部