XQuery, shared with XSLT and XPath 2.0 and later, supports various number data types, two of them are xs:double
and xs:decimal
. It is possible to cast an xs:double
to an xs:decimal
, as defined in http://www.w3.org/TR/xquery-operators/#casting-to-numerics.
Implementations done in Java seem to implement xs:double
using the Java double
data type and xs:decimal
using the java.math.BigDecimal
class. That class supports two ways of converting a double
into a BigDecimal
, namely doing BigDecimal.valueOf(doubleValue)
and new BigDecimal(doubleValue)
. According to https://mcmap.net/q/159288/-bigdecimal-to-use-new-or-valueof, the former gives the more intuitive result while the latter gives the more correct result, as for instance BigDecimal.valueOf(1.1)
results in 1.1
while new BigDecimal(1.1)
results in 1.100000000000000088817841970012523233890533447265625
.
When I try the cast of an xs:double
to an xs:decimal
with Saxon and Exist then
xquery version "1.0";
let $d1 as xs:double := 1.1E0
return xs:decimal($d1)
outputs 1.100000000000000088817841970012523233890533447265625
while with BaseX it outputs 1.1
. I suppose the difference results from the different implementations, BaseX doing BigDecimal.valueOf(1.1)
, Saxon and Exist doing new BigDecimal(1.1)
.
My question is: which approach is the right one to implement the cast operation according to the http://www.w3.org/TR/xquery-operators/#casting-to-numerics?
If ST is xs:float or xs:double, then TV is the xs:decimal value, within the set of xs:decimal values that the implementation is capable of representing, that is numerically closest to SV
and I would say both return the numerically closest value the processor is able to handle. – Idio