W3C home > Mailing lists > Public > public-qt-comments@w3.org > December 2008

[Bug 6240] [FO] round-half-up(value,precision)

From: <bugzilla@wiggum.w3.org>
Date: Mon, 01 Dec 2008 12:48:52 +0000
To: public-qt-comments@w3.org
Message-Id: <E1L78Cq-0008Jq-I9@farnsworth.w3.org>

http://www.w3.org/Bugs/Public/show_bug.cgi?id=6240





--- Comment #2 from Michael Kay <mike@saxonica.com>  2008-12-01 12:48:52 ---
Proposal: define a 2-argument version of fn:round, where the second argument is
used to indicate the required precision in the same way as
fn:round-half-to-even.

The two functions round() and round-half-to-even() should then be the same
except for the way that they round values that are half-way between two
multiples of 10^-p. Currently round-half-to-even always casts the argument to a
decimal; this would be inappropriate for fn:round because it could introduce
errors for large doubles that can't be so converted. So the proposal is to
state (in line with format-number()) that the conversion to decimal must not
lose precision. Proposed text for the two functions is therefore shown below,
with differences tagged as appropriate.

<rh2e>
fn:round-half-to-even($arg as numeric?) as numeric?
fn:round-half-to-even($arg as numeric?, $precision as xs:integer) as numeric?
</rhte>
<round>
fn:round($arg as numeric?) as numeric?
fn:round($arg as numeric?, $precision as xs:integer) as numeric?
</round>
Summary: The value returned is the nearest (that is, numerically closest) value
to $arg that is a multiple of ten to the power of minus $precision. If two such
values are equally near (e.g. if the fractional part in $arg is exactly
.500...), the function returns <rh2e>the one whose least significant digit is
even</rh2e><round>the one that is closest to positive infinity</round>.

If the type of $arg is one of the four numeric types xs:float, xs:double,
xs:decimal or xs:integer the type of the result is the same as the type of
$arg. If the type of $arg is a type derived from one of the numeric types, the
result is an instance of the base numeric type.

The first signature of this function produces the same result as the second
signature with $precision=0.

For arguments of type xs:float and xs:double, if the argument is NaN, positive
or negative zero, or positive or negative infinity, then the result is the same
as the argument. In other cases, the argument is cast to xs:decimal using an
implementation of xs:decimal that imposes no limits on the number of digits
that can be represented. The function is applied to this xs:decimal value, and
the resulting xs:decimal is cast back to xs:float or xs:double as appropriate
to form the function result. If the resulting xs:decimal value is zero, then
positive or negative zero is returned according to the sign of the original
argument.

If $arg is of type xs:float or xs:double, rounding occurs on the value of the
mantissa computed with exponent = 0.

For detailed type semantics, see Section 7.2.3 The fn:abs, fn:ceiling,
fn:floor, fn:round, and fn:round-half-to-even functionsFS

Note:

This function is typically used with a non-zero $precision in financial
applications where the argument is of type xs:decimal. For arguments of type
xs:float and xs:double the results may be counterintuitive. For example,
consider <rh2e>round-half-to-even(xs:float(150.0150), 2)</rh2e><round>[some
similar example]</round>.

<rh2e>The implementation will convert the argument to the xs:decimal
150.014999389... which will then be rounded to the xs:decimal 150.01 which will
be converted back to the xs:float whose exact value is 150.0099945068...
whereas round-half-to-even(xs:decimal(150.0150), 2) will result in the
xs:decimal whose exact value is 150.02.</rh2e><round>[some similar
example]</round>

Note:
fn:round() and fn:round-half-to-even() produce the same result in all cases
except when the argument is exactly midway between two multiples of 10 to the
power of -$precision.

<round>Other ways of rounding midway values can be achieved as follows. Towards
negative infinity: -fn:round(-$x)). Away from zero:
fn:round(fn:abs($x))*fn:compare($x,0). Towards zero:
fn:abs(fn:round(-$x))*-fn:compare($x,0)</round>


-- 
Configure bugmail: http://www.w3.org/Bugs/Public/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
Received on Monday, 1 December 2008 12:49:02 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 7 January 2015 15:45:38 UTC