XQuery, совместно используемый с XSLT и XPath 2.0 и более поздними версиями, поддерживает различные числовые типы данных, два из которых - xs:double
и xs:decimal
. Можно преобразовать xs:double
в xs:decimal
, как определено в http://www.w3.org/TR/xquery-operators/#casting-to-numerics.
Реализации, выполненные на Java, похоже, реализуют xs:double
с использованием типа данных Java double
и xs:decimal
с использованием класса java.math.BigDecimal
. Этот класс поддерживает два способа преобразования double
в BigDecimal
, а именно выполнение BigDecimal.valueOf(doubleValue)
и new BigDecimal(doubleValue)
. Согласно https://stackoverflow.com/a/7186298/252228, первое дает более интуитивный результат, а второе дает более правильный результат, например, BigDecimal.valueOf(1.1)
дает 1.1
, а new BigDecimal(1.1)
дает 1.100000000000000088817841970012523233890533447265625
.
Когда я пробую преобразовать xs:double
в xs:decimal
с Saxon и Exist, тогда
xquery version "1.0";
let $d1 as xs:double := 1.1E0
return xs:decimal($d1)
выводит 1.100000000000000088817841970012523233890533447265625
, а с BaseX выводит 1.1
. Я полагаю, что разница связана с разными реализациями: BaseX выполняет BigDecimal.valueOf(1.1)
, Saxon и Exist выполняет new BigDecimal(1.1)
.
Мой вопрос: какой подход является правильным для реализации операции приведения в соответствии с 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
, и я бы сказал, что оба возвращают самое близкое численное значение, которое процессор может обработать. - person dirkk   schedule 02.02.2015