XSLT and XPath function reference in alphabetical order
(Excerpt from “XSLT 2.0 & XPath 2.0” by Frank Bongers, chapter 5, translated from German)
Rounding functions for numeric types
A numeric value of the same numeric type as the input value, rounded according to the value of the precision argument.
Optional. The argument is an input value of any numeric type which is interpreted as number to be rounded. If the value does not correspond to one of the numeric data types or a type derived thereof, a type error occurs.
Optional. A precision indication in form of any positive or negative xs:integer integer. If 0 is passed on as argument, it does not correspond to the argument passed on.
Purpose of use:
The fn:round-half-to-even() function rounds numerical input values to a determinable number of positions before or after the decimal place, according to a precision indication passed on. The data type of the number is maintained. If the input number is already an integer, the value remains unchanged. If the input value is not one of the four numeric types xs:float, xs:double, xs:decimal or xs:integer or a type derived from these, a type error is reported.
If the input value has the xs:untypedAtomic type, it is cast to xs:double by means of type promotion.
If the input type is a type derived from one of the numeric base types (derived type), the rounding result is returned typed with the appropriate base type.
If the empty sequence is passed on to the function, it also returns the empty sequence. If (for the input types xs:double or xs:float) the input value is NaN, NaN is also returned.
As long as no explicit precision indication is available or if the value 0 is passed on as second argument, the function basically acts like fn:round(), which means it rounds up or down to the next integer.
However, there is a difference in the handling of values being exactly on the threshold between rounding up and down: If the digit after the smallest place to be rounded is a 5, the last place to the nearest even digit (»half to even«) is rounded up or down:
1.25 with precision +1 is rounded down to 1.2, and not (as perhaps expected) rounded up to 1.3.
However, the value 1.35 with precision +1 is rounded up to 1.4.
If a number to be rounded of xs:float or xs:double type is available in exponential form, the rounding always occurs in the mantissa of the number converted to the exponent 0: For example, 1.234E+2 is firstly transformed to the form 123.4E+0 and the particle 123.4 (the mantissa) is rounded according to the valid precision indication.
If the input value is a positive or a negative zero (necessarily of xs:float or xs:double type), the function shows a transparent behaviour. Therefore, for example, it returns -0 for -0; accordingly +0 for +0.
Precision indication greater than 0:
A positive integer as precision argument passed on determines the number of the decimal places to be maintained. Formally, for a value n rounding is done to the nearest place of the input value which corresponds to 10E-n, for n=2 to 10E-2, meaning hundredths (accordingly two decimal places).
Precision indication equals 0:
The 0 as precision argument effects the rounding to integers. According to the formula, for n=0 the precision 10E0 applies which corresponds to the first place left of the decimal point (units). The impact exactly corresponds to the one when omitting the precision argument.
Precision indication less than 0:
A negative integer as precision indication effects the rounding to the left of the decimal point. According to the formula, for n=-2 the precision 10E-(-2) applies, in other words 10E2, which means to hundreds (two places left of the decimal point). The smaller places left of the decimal point, here the tens and the units, are nilled.
Example 1 – rounding without precision argument:
results in: 4.
The precision 0 is assumed because no appropriate argument was passed on. It is rounded to integers. Since the input number is exactly on the rounding threshold, it is rounded up to 4.
Example 2 – rounding with precision argument 0:
results in: 2.
Rounding is done according to the precision 0 passed on to integers. Since the input number is exactly on the rounding threshold, it is rounded down to 2. (With the same argument, fn:round() would return the value 3!)
Example 3 – rounding with positive precision argument:
results in: 123.46.
Rounding is done according to precision 2 to hundredths (two decimal places). Since the place after the last point to be rounded is above the rounding threshold, it is rounded up.
Example 4 – rounding with positive precision argument:
results in: 0.0E0.
Rounding is done according to precision 2 to hundredths (two decimal places). Since the number is in exponential form, its matissa is firslty transformed to the form corresponding to the exponent +0 and then rounded: 3.4567E-3 corresponds to 0.0034567E+0. Therefore, this value is rounded down to 0 (more exactly to 0.0E0) in the scope of the precision.
Example 5 – rounding with negative precision argument:
results in: 120.
Rounding is done according to precision -1 to tens. Since the last place to be rounded in the input number (the unit) is above the rounding threshold, it is rounded up.
Example 6 – rounding with negative precision argument:
results in: 15600.
Rounding is done according to precision -2 to hundreds.
The function is not available.
fn:round-half-to-even($arg as numeric?) as numeric?
fn:round-half-to-even($arg as numeric?,
$precision as xs:integer) as numeric?
|<< back||next >>|
Copyright © Galileo Press, Bonn 2008
Printing of the online version is permitted exclusively for private use. Otherwise this chapter from the book "XSLT 2.0 & XPath 2.0" is subject to the same provisions as those applicable for the hardcover edition: The work including all its components is protected by copyright. All rights reserved, including reproduction, translation, microfilming as well as storage and processing in electronic systems.
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Germany