找回密码
 立即注册

QQ登录

只需一步,快速开始

yue1859921
初级会员   /  发表于:2024-3-29 16:13  /   查看:5894  /  回复:15
1金币
本帖最后由 Richard.Huang 于 2024-4-7 09:38 编辑

产品:SpreadJS、GcExcel
版本:SpreadJSV17.0.5、GcExcelV6.2.2
调研编号:SJS-23641

SpreadJS表格中显示的数据是0.6,用Gcexcel转换成PDF后 变成0.5
SpreadJS表格的数据是通过sheet引用及函数计算的出来的值
download.png


GcExcel转换成PDF后,显示的却是0.5
convpdf.png

ssjon见附件

test0329.zip

5.76 KB, 下载次数: 1793

最佳答案

查看完整内容

目测这是限制,引申到IEEE754的双精度浮点数的运算精度问题了。https://en.wikipedia.org/wiki/IEEE_754 因为这个标准的设定,天生的,在不同系统下浮点数运算必然会产生浮点误差。 然后各个产品在内部进行精度处理了,只不过貌似Excel在这里的处理貌似因为某种考虑没做? 具体的,你可以打开浏览器的开发者工具,在地下试试这个

15 个回复

倒序浏览
最佳答案
最佳答案
前端小白
超级版主   /  发表于:2024-3-29 16:13:15
来自 7#
本帖最后由 前端小白 于 2024-4-3 09:37 编辑

目测这是限制,引申到IEEE754的双精度浮点数的运算精度问题了。https://en.wikipedia.org/wiki/IEEE_754
因为这个标准的设定,天生的,在不同系统下浮点数运算必然会产生浮点误差。
然后各个产品在内部进行精度处理了,只不过貌似Excel在这里的处理貌似因为某种考虑没做?

具体的,你可以打开浏览器的开发者工具,在地下试试这个
image.png431160888.png
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-3-29 17:18:04
2#
本帖最后由 Richard.Huang 于 2024-3-29 17:36 编辑

您好,经过调研,您的这份ssjson文件中计算结果为0.6的单元格上设置了格式为保留一位小数,我们详细跟踪了该单元格的计算的真实值,发现该单元格的真实值实际为0.549999999

而SpreadJS中计算得到该单元格值为0.55,这就造成GcExcel在格式化时,格式化为了0.5,而SpreadJS格式化为了0.6。即该问题并不是GcExcel的问题,GcExcel的结果和Excel计算结果一致

至于对SpreadJS计算成0.6的现象是否是一个问题亦或是使用方法不正确,我们还需要进行进一步的调研。后续有相关调研进展我会第一时间在本贴中进行跟进。
调研编号:SJS-23641

image.png724583739.png
image.png366868895.png

回复 使用道具 举报
yue1859921
初级会员   /  发表于:2024-3-29 18:31:59
3#
本帖最后由 yue1859921 于 2024-3-29 18:37 编辑
Richard.Huang 发表于 2024-3-29 17:18
您好,经过调研,您的这份ssjson文件中计算结果为0.6的单元格上设置了格式为保留一位小数,我们详细跟踪了 ...

麻烦 尽快调研一下  为什么 真实值实际为0.549999999  
表格里的值 都是精确值 没看到有无穷小数
另外,我spreadjs实际使用的版本是 16.1.4
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-4-1 12:25:44
4#
yue1859921 发表于 2024-3-29 18:31
麻烦 尽快调研一下  为什么 真实值实际为0.549999999  
表格里的值 都是精确值 没看到有无穷小数
另外 ...

了解了,相关调研需要正在进行中,还请您稍作等待,后续有相关进展我都会在本贴中进行及时跟进
回复 使用道具 举报
Richard.HuangSpreadJS 开发认证
超级版主   /  发表于:2024-4-2 18:00:01
5#
yue1859921 发表于 2024-3-29 18:31
麻烦 尽快调研一下  为什么 真实值实际为0.549999999  
表格里的值 都是精确值 没看到有无穷小数
另外 ...

最新调研进展:本贴中提及的问题和我前面解释的一致,因为SpreadJS,给您的单元格计算结果为0.55,格式化保留一位小数,于是变成了0.6,而Excel计算结果为0.549999999999970,保留一位小数,格式化为0.5。因此造成了以上的问题。
归根结底是因为SpreadJS和Excel计算精度不一致造成的,您可以用以下代码设置计算精度来解决该问题
  1. GC.Spread.CalcEngine.Functions.CALC_PRECISION = 17// 这里的17其实指的是有效数字(不仅仅是小数)
复制代码
image.png413818969.png
回复 使用道具 举报
yue1859921
初级会员   /  发表于:2024-4-2 19:48:25
6#
本帖最后由 yue1859921 于 2024-4-2 20:00 编辑

SpreadJS,单元格计算结果为0.55   这个值 的确是一个正确的值  根据表格里的公式我自己手算也是0.55啊
我在Excel里用按照公式算也是0.55

为什么在系统里会变成0.549999999999970 ,这个值是怎么得来的 ?本身也没有无穷小数        这和实际值有差异。 明明计算出来是0.55,在系统里一算变成0.5
对于用户根本不了解这里的所以然,只会拿实际看到的值去计算



回复 使用道具 举报
前端小白
超级版主   /  发表于:2024-4-3 09:40:47
8#
yue1859921 发表于 2024-4-2 19:48
SpreadJS,单元格计算结果为0.55   这个值 的确是一个正确的值  根据表格里的公式我自己手算也是0.55啊
...

所以俺们在设计表格的时候,尽量会放宽精度,向这种0.0,很容易出现精度误差。
0.14 -> 0.0,就变成0.1
0.15 -> 0.0,   就变成0.2

少了0.01,肉眼看到的带来的精度是0.1, 如果这个数据是需要肉眼审核的,比如打印或导出,那么将是非常危险的。曾看到一实验室数据报告就这个类型,真怕他们搞实验弄炸了。
回复 使用道具 举报
yue1859921
初级会员   /  发表于:2024-4-3 10:10:32
9#
本帖最后由 yue1859921 于 2024-4-3 10:15 编辑
前端小白 发表于 2024-4-3 09:23
目测这是限制,引申到IEEE754的双精度浮点数的运算精度问题了。https://en.wikipedia.org/wiki/IEEE_754
...

这个原因对于计算机专业的了解,但是用户用表格来做数据的计算 肯定按实际肉眼看到的为主,
50.55-50.0  就算就是等于0.55 一位后 0.6
既然 spreadjs 表格都计算出 等于0.6   怎么能在GCEXCEL里 保证一致?
回复 使用道具 举报
前端小白
超级版主   /  发表于:2024-4-3 10:49:13
10#
这就是我说的问题啊。
0.14 -> 0.0,就变成0.1
0.15 -> 0.0,   就变成0.2

这类问题,不是说保持一致不一致的问题,而是怎么去弱化这类问题。因为无法消除双精度浮点数误差。
从你的描述上,核心问题归纳出来不是
1. GcExcel和Excel算的一样,虽然结果是错的。
2. SpreadJS和Excel算的不一样,但是结果是对的。

你要是的一个正确的计算结果,还是第一个错误的和Excel一样的数据。

从某种意义上来说,诉求矛盾了,这就是我说的,应该放宽格式化的精度,来弱化这种问题。
因为这类问题避免不了的

评分

参与人数 1金币 +200 收起 理由
Richard.Huang + 200 很给力!

查看全部评分

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