【问题标题】:How can the "<" or ">" operators overflow? [duplicate]“<”或“>”运算符如何溢出? [复制]
【发布时间】:2014-07-15 09:16:26
【问题描述】:

我对 Java 中 System.nanoTime() 方法的文档中的以下语句很感兴趣:

long t0 = System.nanoTime();

...

long t1 = System.nanoTime();

应该使用t1 - t0 &lt; 0,而不是t1 &lt; t0,因为可能出现数值溢出

来源:http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#nanoTime()

为什么t1 &lt; t0 可能“溢出”?这在 Javadocs 中,但我想它适用于任何语言。

【问题讨论】:

标签: java jvm operators overflow nanotime


【解决方案1】:

不是&lt;会溢出,而是t2会溢出。

十六进制示例,因为十六进制溢出很明显。

假设您调用System.nanoTime(),结果是0x7FFFFFFF00000000。这非常接近long 的最大值。这是t1

几秒钟后你再次调用它,并得到0x8000000011111111。这非常接近long 的最小值——这意味着它比你得到的第一个值要小得多!这是t2

如果你检查t2 &lt; t1,你会得到false,因为t2确实小于t1

如果你计算差值t2 - t1,这也会溢出,但碰巧这总是会抵消第一次溢出(如果有的话)。结果是0x0000000111111111,这是正确的时差。这大于 0,所以t2 - t1 &gt; 0 返回true

【讨论】:

  • @DavidWallace 那么你的计算是错误的;这将是 2306 年或之前的问题。记住它是 2^64 nano秒。
【解决方案2】:

除了immibis说的,这个源码解释了a

    long t1 = Long.MAX_VALUE;
    long t2 = Long.MIN_VALUE;
    //should have the same result with small longs, but is different when rotating from max value to min value of Long
    System.out.println(t1 - t2 < 0); //true
    System.out.println(t1 < t2); //false

    //should have the same result
    System.out.println(t1 - t2 > 0); // false
    System.out.println(t1 > t2); //true

    System.out.println(t2 - t1); // 1 => 1 nanosecond of difference

由于 nanosceond 中的时间可以超过“long”大小,当时间到达最大值时,它会再次开始到最小值。所以 MAX_VALUE 和 MIN_VALUE 之间有 1 纳秒的差异

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多