XPath输出.07 * 100 * 100为700.00000000000011为什么?

时间:2012-09-18 10:54:17

标签: xslt xpath precision

我注意到一些我无法理解的奇怪的精确行为,我有一些XML:

<CLD>
    <UCRV>
        <UCR1>.07</UCR1>
    </UCRV>
</CLD>

在XSLT文件中,我选择的值为便士(或看起来是100便士,我不知道为什么,但这是客户想要的!):

<xsl:value-of select="./s0:CLD/s0:UCRV/s0:UCR1/text() * 100 * 100"/>

但输出为700.00000000000011数据类型为xsd:Decimal。这里有一些默认的精确度吗?我可以简单地对数字进行舍入,但我只想更好地理解它。

由于

3 个答案:

答案 0 :(得分:5)

浮点数不能准确表示所有内容。由于数字以二进制形式存储,因此有时以二进制形式显示易于编写的数字实际上只能以二进制形式进行处理。这是0.07的情况,它在内部存储为0.070000000000000011,就像你的情况一样。根据经验,您永远不应该信任浮点值,以便直接比较它们而不进行舍入。

答案 1 :(得分:4)

正如人们已经解释的那样,XPath中使用的唯一数字类型是xs:double

number() 功能可将值转换为double。因此,对XPath 1.0中的数字进行操作有时会导致精度损失。

存在不同的解决方案

  1. 使用 round() 功能。您也可以使用 floor() ceiling() 功能。

  2. 使用XSLT format-number() 功能()或 <xsl:number> 指示。

  3. 请注意,XPath 2.0支持所有XSD数字类型,包括xs:decimal。不会导致精度损失的XPath 2.0表达式是:

    xs:decimal(0.07)*100*100
    

答案 2 :(得分:3)

这是标准浮点数学。在这里,有一个最大的位数来拟合数字,并且数字以科学形式保存为二进制。这里0.07不能精确表示,并保持为0.070000000000000011。

有关标题wikipediaWhat Every Computer Scientist Should Know About Floating-Point Arithmetic

的详情,请参阅有关SO的许多问题(尽管使用其他语言)