Rounding Numbers to a Specified Precision

Problem

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

Solution

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.

Discussion

This multiply, round, and divide technique works well as long as the numbers involved remain within the representational ...

Get XSLT Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.