SaxonHE XQuery sum运算精度异常原因及正确结果获取方法
出现问题的原因
- 精度偏差原因:Saxon HE默认会将无显式类型定义的XML节点文本解析为
xs:double双精度浮点数类型。双精度浮点数采用二进制存储,绝大多数十进制小数无法被精确表示,多步累加后会放大精度误差,最终出现末尾非预期的小数位。 - 科学计数法展示原因:Saxon对
xs:double类型的输出有默认规则,当数值绝对值≥106或<10-3时,会自动采用科学计数法格式化输出。
解决方案
要同时解决精度和输出格式问题,可按以下步骤修改XQuery逻辑:
- 显式将所有待求和的节点值转换为
xs:decimal十进制高精度类型,从根源避免二进制浮点数的精度丢失问题 - 使用
format-number函数指定输出格式,禁用科学计数法,按需控制小数位数
正确代码示例
declare namespace xs = "http://www.w3.org/2001/XMLSchema"; let $s := (/root/a, /root/b, /root/c, /root/d, /root/e) ! xs:decimal(.), $sumVal := sum($s) (: 如需固定保留2位小数可将格式串改为"0.00" :) return format-number($sumVal, "0.##")
执行后即可得到预期结果68981506.07。
内容的提问来源于stack exchange,提问作者Dmitriy
相关产品推荐
相关产品推荐

