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 重温IEEE-754双精度(64位浮点)vs.长精度(64位整数)_Java_Javascript_Double_Long Integer_Ieee 754 - Fatal编程技术网

Java 重温IEEE-754双精度(64位浮点)vs.长精度(64位整数)

Java 重温IEEE-754双精度(64位浮点)vs.长精度(64位整数),java,javascript,double,long-integer,ieee-754,Java,Javascript,Double,Long Integer,Ieee 754,我在重温一个问题(),就我而言,这个问题已经完全解决了。问题在于检测特定数值何时会溢出JavaScript的IEEE-754数字类型。上一个问题是使用C#,标记的答案非常有效 现在我正在做完全相同的任务,但这次是用Java,它不起作用。另外,Java使用IEEE-754作为其double数据类型。因此,我应该能够来回投射它,以迫使精度的损失,但它是往返的。对此感到困惑,我开始深入研究Java,现在我真的很困惑 在C#和Java中,long的最小值和最大值是相同的: long MIN_VALUE

我在重温一个问题(),就我而言,这个问题已经完全解决了。问题在于检测特定数值何时会溢出JavaScript的IEEE-754数字类型。上一个问题是使用C#,标记的答案非常有效

现在我正在做完全相同的任务,但这次是用Java,它不起作用。另外,Java使用IEEE-754作为其
double
数据类型。因此,我应该能够来回投射它,以迫使精度的损失,但它是往返的。对此感到困惑,我开始深入研究Java,现在我真的很困惑

在C#和Java中,long的最小值和最大值是相同的:

long MIN_VALUE = -9223372036854775808L;
long MAX_VALUE = 9223372036854775807L;
此外,由于指数和符号保留了固定位,这些值超出了IEEE-754中的可表示数字

// this fails in browsers that have stuck with the pure ECMAScript Number format
var str = Number(-9223372036854775808).toFixed();
if ("-9223372036854775808" !== str) { throw new Error("Overflow!"); }
这将返回Java中(值=-9223372036854775808L)的
false

这将返回Java中(值=-9223372036854775808L)的
false

这将为(值=-9223372036854775808L)返回
true
,但精度较低:

boolean invalidIEEE754(long value) {
    return (0x0L != (0xFFF0000000000000L & (value < 0L ? -value : value)));
}

-9223372036854775808L
可表示为IEEE-754双精度数字。它正是
-2^63
,具有双重表示
-1.0 x 2^63
和编码
0xc3e000000000000

Double能够表示比这个大得多的数字。但是,它不能表示可表示数字范围内的所有整数。例如,如果向数字中添加一个,则会得到
-9223372036854775807=-2^63+1
,该值不能表示为双精度值,并且在往返转换过程中无法存活

-2^63+1
转换为double会将其四舍五入为最接近的可表示的double值,即
-2^63
;转换回long将保留该值

编辑:您在什么平台上进行JavaScript测试?在当前的狩猎中

"-9223372036854775808" === Number(-9223372036854775808).toFixed()

计算结果为
True

这两种方法都会为我返回
false
。JDK1.6.0_21.0很有趣!现在我真的很困惑。我的是通过JUnit运行的,但也应该在JDK 1.6.0_21上。你能显示完整的测试用例吗?很抱歉,我交换了真/假!在谈论这件事时,有太多的不可能。很抱歉给你带来了困惑。你的结果和我的一样,也很有趣。听起来我选择了一个糟糕的测试用例!但是为什么它会在C#中工作?麦卡米:如果它在C#中真的“起作用”,那就违反了IEEE-754标准。你注意到了吗?是的,这是我的测试用例,它“通过了”:)然后我把它移到了Java上,它不是<代码>(Long.MIN\u值+1)和
(Long.MAX\u值-1)
按预期工作。铸造简单。现在我关心的是C#的实现…@McCamey:我不认为微软声称C#遵守IEEE-754,但这相当令人震惊。如果你找不到错误行为的好理由,我会提交错误报告。
boolean invalidIEEE754(long value) {
    return (0x0L != (0xFFF0000000000000L & (value < 0L ? -value : value)));
}
import static org.junit.Assert.*;
import org.junit.Test;

public class FooTests {

    @Test
    public void ieee754One() {
        assertTrue(((long)((double)Long.MIN_VALUE)) != Long.MIN_VALUE);
    }

    @Test
    public void ieee754Two() {
        long bits = Double.doubleToLongBits(Long.valueOf(Long.MIN_VALUE).doubleValue());
        long roundtrip = Double.valueOf(Double.longBitsToDouble(bits)).longValue();

        assertTrue(Long.MIN_VALUE != roundtrip);
    }

    @Test
    public void ieee754Three() {
        long bits = Double.doubleToRawLongBits(Long.valueOf(Long.MIN_VALUE).doubleValue());
        long roundtrip = Double.valueOf(Double.longBitsToDouble(bits)).longValue();

        assertTrue(Long.MIN_VALUE != roundtrip);
    }
}
"-9223372036854775808" === Number(-9223372036854775808).toFixed()