How to rounding-off numbers to a specified precision in xslt 1.0

Posted on Updated on

java-logoRecently we faced an issue to fixed round up a number upto specified precision number in xslt 1.0, there is no any function provided in this version to get resolved it. After a long dig and visited a tone of sites, finally we found the solution as given below :-

 

Rounding Numbers to a Specified Precision

Problem

You want to round to a specific number of decimal places; however, XSLT’s round, ceiling, and floorfunctions always map numbers to integer values.

Solution

XSLT 1.0

Multiply, round, and divide using a power of ten that determines how many decimal digits are required. Assuming $pi = 3.1415926535897932:

<xsl:value-of select="round($pi * 10000) div 10000"/>

 

results in 3.1416. Similarily:

<xsl:value-of select="ceiling($pi * 10000) div 10000"/>

 

results in 3.1416, and:

<xsl:value-of select="floor($pi * 10000) div 10000"/>

 

results in 3.1415.

Rounding to a specific number of decimal places is also achieved using format-number():

<xsl:value-of select="format-number($pi,'#.####')"/>

 

This results in 3.1416. This will work even if more than one significant digit is in the whole part because format-number never uses a format specification as an indication to remove significant digits from the whole part:

<xsl:value-of select="format-number($pi * 100,'#.####')"/>

 

This results in 314.1593.

You can use format-number to get the effect of truncating rather than rounding by using one more formatting digit than required and then chopping off the last character:

<xsl:variable name="pi-to-5-sig" select="format-number($pi,'#.#####')"/>
<xsl:value-of select="substring($pi-to-5-sig,1,string-length($pi-to-5-sig) -1)"/>

 

This results in 3.1415.

XSLT 2.0

The new XPath 2.0 round-half-to-even( ) function will do the trick for most applications. The half to even rule means that when the value being rounded is smack between the lower and higher values, then rounding will be in the direction that produces an even result. So round-half-to-even(1.115,2) eq 1.12 and round-half-to-even(1.125,2) eq 1.12 also! In the first case, we round up because 2 is even, and the second rounds down because 3 is not. The theory behind this is that if you have a bunch of numbers, you should roughly round up as often as you round down so rounding errors cancel out. As you probably guessed, the second argument is the number of decimal places to round to.

If your application mandates that 5 in the last decimal place always rounds upward, you can use the techniques employed in the XSLT 1.0 recipe.

Discussion

The multiply, round, and divide technique works well as long as the numbers involved remain within the representational limits of IEEE floating point. If you try to capture too many places after the decimal, then the rules of IEEE floating point will interfere with the expected result. For example, trying to pick up 16 decimal digits of pi will give you only 15:

<xsl:value-of select="round($pi * 10000000000000000) div 10000000000000000"/>

 

This results in 3.141592653589793, not 3.1415926535897932.

An alternative technique manipulates the number as a string and truncates:

<xsl:value-of select="concat(substring-before($pi,'.'), '.',  substring(substring-after($pi,'.'),1,4))"/>

 

and results in 3.1415.

The effect of ceiling or round can be obtained by this technique at the cost of additional complexity:


<xsl:variable name="whole" select="substring-before($pi,'.')"/> 
<xsl:variable name="frac" select="substring-after($pi,'.')"/>
<xsl:value-of select="concat($whole, '.',  substring($frac,1,3), round(substring($frac,4,2) div 10))"/>

 

This results in 3.1416.

ref link :-
http://flylib.com/books/en/2.765.1.41/1/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s