以下 SPARQL 查询在两个流行 SDK( JenaSesame / 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 标准的意义上来说,无论数学正确性如何)?

最佳答案

这种差异是由 Sesame 的除法运算符实现中采用的不同舍入/缩放策略来解释的。

第一个操作符:

1 / 3 as ?v

将两个整数值相除并将结果绑定(bind)到 ?v,这将是一个十进制类型的值。

由于 1/3 是具有非终止小数扩展的分数,因此我们需要对结果进行四舍五入。但是,由于两个输入变量的小数位数(即小数位数)为零,Sesame 的 MathUtil 也将结果的小数位数设置为零,因此除法的结果(0.3333...)被缩放为零位数并四舍五入,结果为 0。

您可以在 Sesame 中通过向输入值显式添加比例来解决此问题。例如:
SELECT  ?v1
WHERE
{
    BIND ( 1.0000 / 3 as ?v1)
}

将导致:
?v1:  "0.3333"^^<http://www.w3.org/2001/XMLSchema#decimal>

请注意,我们在这里实际做的是将您的输入值之一从整数更改为小数。这有点类似于在 Java 中执行 1/3 将导致 0,但您可以通过强制转换为 double 来解决这个问题。

据我从 XPath 规范(它定义了 SPARQL 重用的除法运算符)来看,Jena 和 Sesame 的行为都符合规范,因为数字运算的缩放数的选择是实现定义的。

当然,这并不是说如果芝麻真的在做除法时对这种重复分数使用更高的精度就不会更实用。在 http://www.openrdf.org/issues/browse/SES-1063 记录为改进请求,由于这是一件微不足道的事情,因此将在下一个版本中支持。同时,我希望以上内容为您提供了合适的解决方法。

关于sparql - 为什么Jean和Sesame/OpenRDF的SPARQL处理器对除法运算的解释会发生变化?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11551700/

10-13 01:11