Subject: RE: 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: 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>
|