From: Pavel Novy <novy@fe...>  20050811 16:02:44

Michael, thanks for your tip. In fact, I'm using Saxon only as an alternative to other XSLT/XPath processors and would like to stay on version 1.0, because not all implementations support version 2.0. Pavel Michael Kay napsal(a): > 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/ 
From: Pavel Novy <novy@fe...>  20050810 12:33:58

Hi there, I noticed a problem with Saxon doing simple mathematical operations (addition, subtract, ...) in my stylesheet. Here is a simple sample which demonstrates the issue (an inaccurate results for some values): <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0"> <xsl:output method="text"/> <xsl:template match="/"> <xsl:valueof select="concat('163.16+100.25=', 163.16+100.25, ' vs. 263.16+0.25=', 263.16+0.25)"/> </xsl:template> </xsl:transform> 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 With Saxon 8.5 (8.4 too) I'm getting this: Warning: Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor 163.16+100.25=263.40999999999997 vs. 263.16+0.25=263.41 When switched to version 2.0 in the stylesheet (what is not intended for my purposes), I'm getting a valid result with Saxon 8.5 (8.4 too): 163.16+100.25=263.41 vs. 263.16+0.25=263.41 Tested on two computers with different OS/JRE version installed, with the same results in all cases (1. Windows 2000/1.5.0_04b05, 2. Windows XP/1.4.2_06b03). Can somebody take a look on this? I'm still not too familiar with this stuff, so maybe I'm doing something wrong... Thanks, Pavel 
From: Martin Honnen <Martin.H<onnen@ar...>  20050810 12:52:37

Pavel Novy wrote: > I noticed a problem with Saxon doing simple mathematical operations > (addition, subtract, ...) in my stylesheet. Here is a simple sample > which demonstrates the issue (an inaccurate results for some values): > > <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; > version="1.0"> > <xsl:output method="text"/> > <xsl:template match="/"> > <xsl:valueof select="concat('163.16+100.25=', 163.16+100.25, ' vs. > 263.16+0.25=', 263.16+0.25)"/> > </xsl:template> > </xsl:transform> > > 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 > > With Saxon 8.5 (8.4 too) I'm getting this: > Warning: Running an XSLT 1.0 stylesheet with an XSLT 2.0 processor > 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 Honnen http://JavaScript.FAQTs.com/ 
From: Pavel Novy <novy@fe...>  20050810 17:29:06

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 
From: Michael Kay <mike@sa...>  20050810 17:59:06

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 > 
From: Pavel Novy <novy@fe...>  20050811 16:02:44

Michael, thanks for your tip. In fact, I'm using Saxon only as an alternative to other XSLT/XPath processors and would like to stay on version 1.0, because not all implementations support version 2.0. Pavel Michael Kay napsal(a): > 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/ 
From: Michael Kay <mike@sa...>  20050811 22:31:26

In that case you'll have to put up with the fact that conversion of decimal numbers to (binary) doubles typically introduces small errors; the usual technique is to hide these from the user by displaying the result to limited precision on output (use formatnumber()). Michael Kay http://www.saxonica.com/ > Original Message > From: saxonhelpadmin@... > [mailto:saxonhelpadmin@...] On Behalf Of > Pavel Novy > Sent: 11 August 2005 17:02 > To: saxonhelp@... > Subject: Re: [saxon] inaccurate results of simple > mathematical operations > > Michael, thanks for your tip. In fact, I'm using Saxon only as an > alternative to other XSLT/XPath processors and would like to stay on > version 1.0, because not all implementations support version 2.0. > > Pavel > > Michael Kay napsal(a): > > 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/ > > >  > 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 > 
From: Pavel Novy <novy@fe...>  20050812 14:18:04

I understand. Could you take a look on my recent contribution with a sample based just on formatnumber()? Thinking more about it, I probably need to extend my code by some range checks to be sure I have an exact result in all cases. I guess it should count on the number of significant decimals of all operands and on their count. Let's assume addition (of very big and/or very small numbers) only. Although, this problem is rather mathematical than XSLT/XPath related :). http://grouper.ieee.org/groups/754/ Pavel Michael Kay napsal(a): > In that case you'll have to put up with the fact that conversion of decimal > numbers to (binary) doubles typically introduces small errors; the usual > technique is to hide these from the user by displaying the result to limited > precision on output (use formatnumber()). > > Michael Kay > http://www.saxonica.com/ 