以下SPARQL查询在两个常用SDK(Jena和Sesame / OpenRDF)的SPARQL引擎上运行时会产生不同的结果:
PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>
SELECT ?v1 ?v2 ?v3 ?v4 ?v5 ?v6
WHERE
{
BIND ( 1 / 3 as ?v1)
BIND ( xsd:float(1 / 3) as ?v2)
BIND ( xsd:float(1) / 3 as ?v3)
BIND ( ( 1.0 / 3) as ?v4)
BIND ( xsd:float(1.0 / 3) as ?v5)
BIND ( xsd:float(1.0) / 3 as ?v6)
}
Jena的最新版本的结果对我有意义(格式化为可读性):
v1: 0.333333333333333333333333
v2: "0.333333333333333333333333"^^xsd:float
v3: "0.33333334"^^xsd:float
v4: 0.333333333333333333333333
v5: "0.333333333333333333333333"^^xsd:float
v6: "0.33333334"^^xsd:float
另一方面,最新版本的Sesame / OpenRDF返回(格式化为可读性):
v1: "0"^^<http://www.w3.org/2001/XMLSchema#decimal>
v2: "0.0"^^<http://www.w3.org/2001/XMLSchema#float>
v3: "0.33333334"^^<http://www.w3.org/2001/XMLSchema#float>
v4: "0.3"^^<http://www.w3.org/2001/XMLSchema#decimal>
v5: "0.3"^^<http://www.w3.org/2001/XMLSchema#float>
v6: "0.33333334"^^<http://www.w3.org/2001/XMLSchema#float>
强调要点:Jena永远不会像Sesame / OpenRDF那样返回0或0.0或0.3。任何人都可以解释为什么数字结果会有这样的差异吗?以及如何将相同的结果提供给相同的SPARQL查询?或者,哪一个是正确的(从某种意义上说,无论数学正确性如何,都能正确实现SPARQL标准)?
答案 0 :(得分:2)
这种差异可以通过Sesame实现除法运算符中采用的不同舍入/缩放策略来解释。
第一个运营商:
1 / 3 as ?v
除以两个整数值并将结果绑定到?v,这将是十进制类型的值。
由于1/3是具有非终止十进制扩展的分数,我们需要对结果进行舍入。但是,由于两个输入变量的比例(即小数位数)为零,因此Sesame的MathUtil也将结果的比例设置为零,因此除法的结果(0.3333 ...)被缩放为零数字并舍入,结果为0。
您可以通过在输入值中明确添加比例来解决此问题。例如:
SELECT ?v1
WHERE
{
BIND ( 1.0000 / 3 as ?v1)
}
将导致:
?v1: "0.3333"^^<http://www.w3.org/2001/XMLSchema#decimal>
请注意,我们实际执行的操作是将您的一个输入值从整数更改为小数。它有点类似于Java中的1/3会导致0,但你可以通过强制转换来加倍。
据我所知,XPath规范(定义了SPARQL重用的除法运算符),Jena和Sesame都符合规范,因为数值运算上的缩放数的选择是实现定义的。
当然,这并不是说如果芝麻在进行分割时实际上对这些重复分数使用了更高的精度,那就更不实际了。在http://www.openrdf.org/issues/browse/SES-1063记录为改进请求,因为这是一件微不足道的事情,所以下一版本将支持此功能。与此同时,我希望上面给出了一个合适的解决方法。