Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java xs:double到xs:decimal的转换应该实现为BigDecimal.valueOf(double)还是新的BigDecimal(double)?_Java_Xquery_Saxon_Exist Db_Basex - Fatal编程技术网

Java xs:double到xs:decimal的转换应该实现为BigDecimal.valueOf(double)还是新的BigDecimal(double)?

Java xs:double到xs:decimal的转换应该实现为BigDecimal.valueOf(double)还是新的BigDecimal(double)?,java,xquery,saxon,exist-db,basex,Java,Xquery,Saxon,Exist Db,Basex,XQuery与XSLT和XPath2.0及更高版本共享,支持各种数字数据类型,其中两种是xs:double和xs:decimal。可以将xs:double强制转换为xs:decimal,如中所定义 在Java中完成的实现似乎使用Javadouble数据类型实现xs:double,并使用Java.math.BigDecimal类实现xs:decimal。该类支持将double转换为BigDecimal的两种方法,即执行BigDecimal.valueOf(doubleValue)和新建BigDec

XQuery与XSLT和XPath2.0及更高版本共享,支持各种数字数据类型,其中两种是
xs:double
xs:decimal
。可以将
xs:double
强制转换为
xs:decimal
,如中所定义

在Java中完成的实现似乎使用Java
double
数据类型实现
xs:double
,并使用
Java.math.BigDecimal
类实现
xs:decimal
。该类支持将
double
转换为
BigDecimal
的两种方法,即执行
BigDecimal.valueOf(doubleValue)
新建BigDecimal(doubleValue)
。根据,前者给出更直观的结果,而后者给出更正确的结果,例如
BigDecimal.valueOf(1.1)
产生
1.1
,而
新的BigDecimal(1.1)
产生
1.1000000000000088817841970012523233890533447265625

当我尝试用Saxon将
xs:double
转换为
xs:decimal
并存在时

xquery version "1.0";

let $d1 as xs:double := 1.1E0
return xs:decimal($d1)
输出
1.1000000000000088817841970012523233890533447265625
,而使用BaseX它输出
1.1
。我认为这种差异是由不同的实现造成的,BaseX执行
BigDecimal.valueOf(1.1)
,Saxon和Exist执行
new BigDecimal(1.1)


我的问题是:根据XQuery的建议,哪种方法是实现cast操作的正确方法取决于双精度值的最接近的十进制表示应该是什么。原因是该规范应该支持任意编程语言的实现


但是,由于您提示
BigDecimal.valueOf(d)
新的BigDecimal(d)
不是等价的,BaseX的下一个版本(8.0版)将返回更准确的结果。

xs:decimal的实现需要支持至少18个有效的十进制数字,如果它支持18个有效的十进制数字,最接近xs:double值1.1的xs:decimal将是1.100000 000088,而不是1.1。(实际上是19位而不是18位,但即使是18位,与1.1的差异也应该显示出来。)因此我认为返回小数点1.1是不一致的。实现定义的位数超过18位,但前18位基本上必须如图所示

Saxon中的实际代码是

public DecimalValue(double in) throws ValidationException {
        try {
            BigDecimal d = new BigDecimal(in);
            value = d.stripTrailingZeros();
        } catch (NumberFormatException err) {
            //...
        }

我想说,无论哪种方法都是正确的,而且所有的实现都正确地实现了规范。它说如果ST是xs:float或xs:double,那么TV是xs:decimal值,在实现能够表示的xs:decimal值集中,在数值上最接近SV,我想说两者都返回处理器能够处理的数值上最接近的值。我不太明白。如果规范中说“至少有18位有效的十进制数字”,为什么返回
1.100000
(可以短接到
1.1
,而不丢失有效数字)是不正确的?我不认为会。1.1和1.100 000只是同一个数字的不同表示形式,因此如果您实际上没有返回任何不同的值。我所说的是,双精度1.1e0的数值与十进制1.1不同,如果您将小数保持在18位或以上,则会显示差异。@MichaelKay,将
格式化数字(xs:decimal(1.1e0),'0.00000000000000000000000')eq'1.100000000000009'
是一个测试用例,如果XQuery 3.0实现的
xs:decimal
至少包含所需的18个有效数字,那么它应该通过该测试吗?@MartinHonnen,是的,我认为这是一个合法的测试,虽然我对将边缘案例放入测试套件的兴趣因为它们往往引起的大量讨论而减弱。。。