Subject: [xsl] Re: format-number/bankers' rounding problem From: daniel whitney <dbf.whitney@xxxxxxxxx> Date: Wed, 13 Jul 2011 12:50:24 -0400 |
Sorry I should have started out by saying that I want positive decimal values to round up and negative decimal values to round down. On Wed, Jul 13, 2011 at 12:28 PM, daniel whitney <dbf.whitney@xxxxxxxxx> wrote: > 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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] format-number/bankers' roundi, daniel whitney | Thread | Re: [xsl] format-number/bankers' ro, Michael Kay |
Re: [xsl] format-number/bankers' ro, David Carlisle | Date | Re: [xsl] format-number/bankers' ro, Michael Kay |
Month |