[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

format-number/bankers' rounding problem

Subject: format-number/bankers' rounding problem
From: daniel whitney <dbf.whitney@xxxxxxxxx>
Date: Wed, 13 Jul 2011 12:42:51 -0400
 format-number/bankers' rounding problem
I saw the round solution on the web, details below...

Java v. 1.6.0_26-b03
Saxon v. 9.1.0.8J
XSL version="1.0"

I hit the problem of bankers' rounding when performing a transform
using Java and Saxon and I think I have a solution that works, but I
wanted to see if my logic is questionable.

Some background:

To do transforms we use Java, Microsoft and PHP based processors. When
using format-number('0.165', '0.00') the output returned is 0.16
(Java), 0.17 (MS) and 0.17 (PHP). I looked on the web for a solution
to this and saw the round solution. I tried it on a small sample of
data and it looked OK but then noticed something strange. With this:
<xsl:value-of select="format-number(round('0.145' * 100) div 100,
'0.00')"/>, using Saxon, the result is 0.14. Other numbers like 0.165
(0.17), or even trying this: format-number(round('0.0145' * 1000) div
1000, '0.000') (0.015), worked.

This also presented another problem. We use an XSL called  template to
format most of our numbers. Parameters it accepts are, of course, the
number, formatting for positive numbers, formatting for negative
numbers, minimum number of decimals and maximum number of decimals. If
I were to use the round number, I would have to write something to
deal with whether to use 100, 1000, 10000 etc to round. Not a huge
deal but .... The clincher though was when I tested the rounding on
negative numbers: <xsl:value-of select="format-number(round('-0.165' *
100) div 100, '(0.00)')"/> (using Saxon) produces "(0.16)". So that
was the nail in the coffin for round.

So what I came up with was just to append '0000001' to the original
decimal (there's already a separate formatting condition for values
with no decimal) and then to format that:           <xsl:value-of
select="format-number(concat($numberValueParam,
'0000001'),$formatNumberVar)"/>

So if $numberValueParam = '0.145' and $formatNumberVar is
'0.00;(0.00)' the value I'm formatting is '0.1450000001' and produces
the output 0.15 and works for both positive and negative values.

I concatenate so many 0's as the maximum number of decimals we might
display is 6 and I wanted to ensure that '0.2' would output as
'0.200000' and not '0.200001'.

This solution is simple for me to implement, so, is there a flaw in my
logic? Better, does something already exist where I can just indicate,
round up for positive and down for negative values?

Thanks for any input,

Dan.

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.