java – 运行时期间最终的非规范NaN双值更改
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 运行时期间最终的非规范NaN双值更改,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2820字,纯文字阅读大概需要5分钟。
内容图文
![java – 运行时期间最终的非规范NaN双值更改](/upload/InfoBanner/zyjiaocheng/826/a97267366e8d472c90fc2a98ebc58d97.jpg)
我正在编写与R交互的Java代码,其中“NA”值与NaN值区分开来. NA表示值“统计上缺失”,即无法收集或无法获得.
class DoubleVector {
public static final double NA = Double.longBitsToDouble(0x7ff0000000001954L);
public static boolean isNA(double input) {
return Double.doubleToRawLongBits(input) == Double.doubleToRawLongBits(NA);
}
/// ...
}
以下单元测试演示了NaN和NA之间的关系,并在我的Windows笔记本电脑上运行良好,但“isNA(NA)#2”有时在我的ubuntu工作站上失败.
@Test
public void test() {
assertFalse("isNA(NaN) #1", DoubleVector.isNA(DoubleVector.NaN));
assertTrue("isNaN(NaN)", Double.isNaN(DoubleVector.NaN));
assertTrue("isNaN(NA)", Double.isNaN(DoubleVector.NA));
assertTrue("isNA(NA) #2", DoubleVector.isNA(DoubleVector.NA));
assertFalse("isNA(NaN)", DoubleVector.isNA(DoubleVector.NaN));
}
从调试开始,看起来DoubleVector.NA被更改为规范的NaN值7ff8000000000000L,但很难分辨,因为将它打印到stdout会给出与调试器不同的值.
此外,如果测试在之前的许多其他测试之后运行,则测试仅失败;如果我单独运行这个测试,它总是通过.
这是一个JVM错误吗?优化的副作用?
测试总是传递:
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode, sharing)
测试有时会失败:
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02, mixed mode)
解决方法:
您正在这里非常危险的水中行走,这是少数几个没有精确指定Java VM行为的区域之一.
根据JVM规范,双范围内只有“NaN值”.对双精度数没有算术运算可以区分两个不同的NaN值.
The documentation of longBitsToDouble()有这个说明:
Note that this method may not be able to return a
double
NaN with exactly same bit pattern as the long argument. IEEE 754 distinguishes between two kinds of NaNs, quiet NaNs and signaling NaNs. The differences between the two kinds of NaN are generally not visible in Java. Arithmetic operations on signaling NaNs turn them into quiet NaNs with a different, but often similar, bit pattern. However, on some processors merely copying a signaling NaN also performs that conversion. In particular, copying a signaling NaN to return it to the calling method may perform this conversion. SolongBitsToDouble
may not be able to return a double with a signaling NaN bit pattern. Consequently, for some long values,doubleToRawLongBits(longBitsToDouble(start))
may not equalstart
. Moreover, which particular bit patterns represent signaling NaNs is platform dependent; although all NaN bit patterns, quiet or signaling, must be in the NaN range identified above.
因此,假设处理double值将始终保持特定的NaN值完整是一件危险的事情.
最干净的解决方案是将数据存储为long,并在检查特殊值后转换为double.然而,这将对性能产生明显的影响.
您可以通过在受影响的地方添加strictfp标志来逃避.这并不以任何方式保证它能够正常工作,但它(可能)会改变JVM处理浮点值的方式,并且可能只是必要的提示.但是,它仍然不便携.
内容总结
以上是互联网集市为您收集整理的java – 运行时期间最终的非规范NaN双值更改全部内容,希望文章能够帮你解决java – 运行时期间最终的非规范NaN双值更改所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。