If you're using Saxon 8.x, the simple answer is to use xs:decimal arithmetic
rather than xs:double arithmetic, which is the default (in this situation)
if you specify version="2.0". You can force xs:decimal arithmetic by casting
values to xs:decimal before totalling, e.g. sum(//item/xs:decimal(.))
Michael Kay
http://www.saxonica.com/
> Original Message
> From: saxonhelpadmin@...
> [mailto:saxonhelpadmin@...] On Behalf Of
> Pavel Novy
> Sent: 10 August 2005 18:29
> To: saxonhelp@...
> Subject: Re: [saxon] inaccurate results of simple
> mathematical operations
>
> Martin Honnen wrote:
> >
> > Pavel Novy wrote:
> >
> >> <xsl:valueof select="concat('163.16+100.25=',
> 163.16+100.25, ' vs.
> >> 263.16+0.25=', 263.16+0.25)"/>
> >>
> >> With Saxon 6.5.4 (and former) I'm getting the following output:
> >> 163.16+100.25=263.40999999999997 vs. 263.16+0.25=263.41
> >
> > XSLT 1.0/XPath 1.0 implement a single number type which
> follows some
> > IEEE standard for double floating point (A number can have any
> > doubleprecision 64bit format IEEE 754 value [IEEE 754].).
> > Other languages (for instance JavaScript/ECMAScript for its
> number type
> > or Java I think for its double type) use that standard too and the
> > "inaccuracy" you observe is simply the result of binary
> representation
> > of numbers. You have to round such a result if you want to
> output with
> > some fixed number of decimals.
> >
> Martin, thanks for your reply.
>
> My goal is to compare a sum of values with its sum already
> contained in
> the same input file to affirm that the file is valid. To do
> it exactly,
> I guess I need to determine maximal number of valid decimal
> places used
> on input. Here is my sample stylesheet based on such an idea with
> testing input and corresponding output:
>
> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> version="1.0">
> <xsl:output method="text"/>
> <xsl:template match="/">
> <xsl:variable name="magic">
> <xsl:foreach select="/values/value">
> <xsl:sort
> select="stringlength(substringafter(string(number(.)), '.'))"
> order="descending"/>
> <xsl:if test="position()=1">
> <xsl:valueof
> select="stringlength(substringafter(string(number(.)), '.'))"/>
> </xsl:if>
> </xsl:foreach>
> </xsl:variable>
> <xsl:variable name="sum" select="sum(/values/value)"/>
> <! Note: limited precision (10 decimal places at most): >
> <xsl:valueof select="concat($sum, ' vs. ', formatnumber($sum,
> substring('0.0000000000', 1, $magic+2)), ' (magic=', $magic, ')')"/>
> </xsl:template>
> </xsl:transform>
>
> Input:
> <values>
> <value>163.16001000</value>
> <value>100.250011</value>
> </values>
>
> Output:
> 263.41002100000003 vs. 263.410021 (magic=6)
>
> With those values on input, I got the same "inaccurate"
> result of sum()
> for XSLT/XPath version 2.0 too (Saxon 8.5)...
>
> Pavel
>
>
> 
> SF.Net email is Sponsored by the Better Software Conference & EXPO
> September 1922, 2005 * San Francisco, CA * Development
> Lifecycle Practices
> Agile & PlanDriven Development * Managing Projects & Teams *
> Testing & QA
> Security * Process Improvement & Measurement *
> http://www.sqe.com/bsce5sf
> _______________________________________________
> saxonhelp mailing list
> saxonhelp@...
> https://lists.sourceforge.net/lists/listinfo/saxonhelp
>
