RE: [xsl] Decimal precision

Subject: RE: [xsl] Decimal precision
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 2 Feb 2005 23:01:36 -0000
You are using

sum(claim/claim_line/reimbursement_amount)

and I suspect you haven't validated the source document against a schema,
which means that reimbursement_amount is an untyped value. When an
untypedAtomic value is supplied as input to a numeric function such as
sum(), then it is treated as a double, and the arithmetic is done in
floating point. You either need to validate against a schema, or you need to
convert to a decimal "by hand":

sum(claim/claim_line/reimbursement_amount/xs:decimal(.))

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: Jim Neff [mailto:jneff@xxxxxxxxxxxxxxx] 
> Sent: 02 February 2005 21:47
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: RE: [xsl] Decimal precision
> 
> Thank you for your response Michael.
> 
> Below is my stylesheet.  I'm using Saxon 8.?
> 
> 
> > So summing a set of money amounts should give you the right 
> > answer without any rounding errors.
> > 
> > Michael Kay
> 
> 
> I am getting rounding errors still.  Is there something I am not doing
> correctly to get this to "auto-detect" decimals for version 2 ?
> 
> I've gotten around this with the format-number function for 
> now.  I was just
> wondering why this didn't work for me as expected.
> 
> I am not using Schemas.  Do I need to, or is there a way to 
> tell the Sum()
> function to make sure it treats claim_line/reimbursement_amount as a
> decimal? 
> 
> I tried sum(xs:decimal(claim_line/reimbursement_amount)) but 
> the parser told
> me where to go with that.
> 
> Or do I just need to break down and learn Schemas?
> 
> 
> Here is my stylesheet:
> 
> <xsl:transform
>    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>    version="2.0"
>    xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
>    exclude-result-prefixes="xs">
>    
>    <xsl:output method="xml" indent="yes"/>
>    <xsl:strip-space elements="*"/>
>    
>    <xsl:template match="claim_file">
>    
>    	<xsl:element name="file_root">
>    
>    		<xsl:apply-templates select="provider" >
> 		
> 			<xsl:sort select="provider_number" 
> order="ascending"
> data-type="number"/>
> 		
> 		</xsl:apply-templates>
> 		
> 	</xsl:element>
> 		   
>    </xsl:template>
>    
>    <xsl:template match="provider">
>    
>    	<xsl:element name="provider">
> 		
> 		<xsl:element name="claim_sum">
> 		
> 			<xsl:value-of
> select="sum(claim/claim_line/reimbursement_amount)"/>
> 					
> 		</xsl:element>		
> 		
> 	</xsl:element>
>    
>    </xsl:template>
>       
> </xsl:transform>
> 
> 
> Sample input xml document:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <claim_file>
>    <provider>
>       <provider_number>123456</provider_number>
>       <claim>
>           <claim_line>
>             <reimbursement_amount>45.00</reimbursement_amount>
>          </claim_line>
>          <claim_line>
>             <reimbursement_amount>23.95</reimbursement_amount>
>          </claim_line>
>          <claim_line>
>             <reimbursement_amount>56.36</reimbursement_amount>
>          </claim_line>
>       </claim>
>       <claim>
>          <claim_line>
>             <reimbursement_amount>45.00</reimbursement_amount>
>          </claim_line>
>          <claim_line>
>             <reimbursement_amount>23.95</reimbursement_amount>
>          </claim_line>
>          <claim_line>
>             <reimbursement_amount>37.04</reimbursement_amount>
>          </claim_line>
>       </claim>
>       <claim>
>          <claim_line>
>             <reimbursement_amount>45.00</reimbursement_amount>
>          </claim_line>
>          <claim_line>
>             <reimbursement_amount>23.95</reimbursement_amount>
>          </claim_line>
>          <claim_line>
>             <reimbursement_amount>37.04</reimbursement_amount>
>          </claim_line>
>       </claim>
>       <claim>
>          <claim_line>
>             <reimbursement_amount>45.00</reimbursement_amount>
>          </claim_line>
>          <claim_line>
>             <reimbursement_amount>23.95</reimbursement_amount>
>          </claim_line>
>          <claim_line>
>             <reimbursement_amount>43.00</reimbursement_amount>
>          </claim_line>
>       </claim>
>    </provider> 
> 
> My output is:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <file_root>
>    <provider>
>       <claim_sum>449.23999999999995</claim_sum>
>    </provider>
> </file_root>

Current Thread