2009-12-04 9 views
3

J'ai ces données XML et essaye d'en faire une somme en utilisant l'extrait XSLT ci-dessous.Problème de diff de somme/bogue dans XSLT 1.0

Xml

<?xml version="1.0" encoding="utf-8"?> 
<values> 
    <value>159.14</value> 
    <value>-2572.50</value> 
    <value>-2572.50</value> 
    <value>2572.50</value> 
    <value>2572.50</value> 
    <value>-159.14</value> 
</values> 

Xslt

<?xml version="1.0" encoding="utf-8"?> 

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/"> 
    <xsl:value-of select="sum(values/value)"/> 
</xsl:template> 

</xsl:stylesheet> 

Dans mon monde la valeur devrait alors être mais il finit par être -0,0000000000005684341886080801

Exécutez-le dans Visual Studio et voyez par vous-même. Pourquoi? Est-ce que cela arrive?

+1

Juste pour ajouter un peu complétude à la solution donnée ci-dessous et répondez à votre question de "Pourquoi?" Jetez un coup d'œil à "Ce que chaque informaticien devrait savoir à propos de l'arithmétique en virgule flottante" http://docs.sun.com/source/806-3568/ncg_goldberg.html – LorenVS

Répondre

5

votre processeur Semble XSLT convertir nombres décimaux chaînes flotter point numéros de précision avant somme;

Eh bien, vous pouvez toujours utiliser la fonction ronde et diviser par votre précision désirée ou d'utiliser la fonction numéro de format, le cas échéant:

<xsl:template match="/"> 
    <xsl:value-of select="round(sum(values/value)) div 100"/><br /> 
    <xsl:value-of select="format-number(sum(values/value), '0.00')"/> 
</xsl:template> 
+1

@Riri: Si vous êtes surpris de ce comportement, je pense ceci: http://stackoverflow.com/questions/249467/what-is-a-simple-example-of-floating-point-rounding-error et la page liée dans la réponse acceptée vaut la peine d'être lue. – Tomalak

1

Comment ajouter round?

round(sum(values/value)) 
+0

Bien sûr, cela résout - mais pourquoi cela se passe-t-il? – Riri

+0

Publié le même commentaire ci-dessus, mais il se sent en place ici aussi. Juste pour ajouter un peu de complétude à la solution donnée ci-dessous et répondre à votre question de "Pourquoi?" Jetez un coup d'œil à "Ce que tout scientifique de l'informatique devrait savoir sur l'arithmétique en virgule flottante" http://docs.sun.com/source/806-3568/ncg%5Fgoldberg.html – LorenVS

2

Essayez cette

<xsl:value-of select="format-number(sum(values/value),'0.00')"/>