Subject: [xsl] format-number/bankers' rounding problem From: daniel whitney <dbf.whitney@xxxxxxxxx> Date: Wed, 13 Jul 2011 12:28:42 -0400 |
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 -> |
---|---|---|
Re: [xsl] why matches($title,'.*?(\, Liam R E Quin | Thread | [xsl] Re: format-number/bankers' ro, daniel whitney |
Re: [xsl] why matches($title,'.*?(\, Michael Kay | Date | [xsl] format-number/bankers' roundi, daniel whitney |
Month |