在JAVA中使用System.nanoTime()时,为什么要使用t1-t0 <0,而不是t1 <t0

use*_*734 18 java math comparison overflow

当我在JAVA中阅读System.nanoTime()API时.我找到了这一行:

一个应该使用t1 - t0 <0,而不是t1 <t0,因为数字溢出的可能性.

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

比较两个nanoTime值

long t0 = System.nanoTime();
...
long t1 = System.nanoTime();
Run Code Online (Sandbox Code Playgroud)

一个应该使用t1 - t0 <0,而不是t1 <t0,因为数字溢出的可能性.

我想知道为什么t1 - t0 < 0防止溢出的最佳方法.

因为我读了一些比其他A < B更优选的线程A - B < 0.

Java Integer compareTo() - 为什么使用比较与减法?

这两件事情是矛盾的.

rol*_*lfl 13

Nano时间不是'真实'时间,它只是一个计数器,当某些未指定的事件发生时(可能是计算机启动),从一些未指定的数字开始递增.

它会溢出,并在某些时候变为负面.如果你t0刚好在它溢出之前(即非常大的正面),并且你t1刚刚经过(非常大的负数),那么t1 < t0(即你的条件是错误的,因为t1之后发生t0).....

但是,如果你说t1 - t0 < 0,好吧,神奇的是,对于相同的溢出(undeflow)原因(非常大的负数减去一个非常大的正向下溢),结果将是t1之后的纳秒数t0....并且是对的.

在这种情况下,两个错误确实是正确的!


Psh*_*emo 8

t0 - t1 < 0t0 < t1当我们确定值的真正差异(溢出之前)不大于包含所有可能值的集合的一半或大小时更好.
对于纳秒,它将是大约292年(纳秒存储在长度中,一半long尺寸是2^64/2= 2^63纳秒〜= 292年).

因此,对于分离时间少于292年的时间样本,我们应该使用t0 - t1 < 0以获得正确的结果.


为了更好地可视化,我们可以说循环包含8个可能的值-4, -3, -2, -1 ,0, 1, 2, 3.

所以时间表看起来像

real time values:  .., -6, -5, -4, -3, -2, -1,  0,  1,  2,  3,  4,  5,  6,  7, ..
overflowed values: ..,  2,  3, -4, -3, -2, -1,  0,  1,  2,  3, -4, -3, -2, -1, ..
Run Code Online (Sandbox Code Playgroud)

让我们来看看差异将如何t0 - t1 < 0t0 < t1将会表现为不会大于4的值(循环大小的一半,-4是最小值,这意味着它可以是计算delta的最小结果).请注意,只有t0 - t1 < 0t1溢出时才会给出正确的结果

  1. delta = 1,溢出值越大(注意:我们不会使较小的值溢出,因为这意味着两个值都处于同一个周期,因此计算将与没有溢出的情况相同)

    • 实际价值: t0 = 3 t1 = 4
    • 溢出: t0 = 3 t1 = -4
    • t0 < t1==> 3 < -4 - > false
    • t0 - t1 < 0==> 3 - (-4) < 0==> -1 < 0(7溢出到-1)为

    所以仅适用于t0 - t1 < 0我们得到正确的结果,尽管或许由于溢出.

  2. delta = 1但这次没有溢出

    a)正值

    • t0 = 2, t1 = 3
    • 2 < 3 真正
    • 2 - 3 < 0==> -1 < 0 是的

    b)负值

    • t0 = -4, t1 = -3
    • -4 < -3 真正
    • -4 - (-3) < 0==> -1 < 0 是的

    对于其中实际delta = 1的其他情况,我们也将获得两者t0 < t1t0 - t1 < 0测试的正确结果(t0 - t1将始终-1)

  3. delta = 3(几乎是周期的一半)

    a1)溢出更大的价值

    • 实际价值: t0 = 3 t1 = 6
    • 溢出: t0 = 3 t1 = -2
    • t0 < t1==> 3 < -2 - > false
    • t0 - t1 < 0==> 3 - (-2) < 0==> -3 < 0(5溢出到-3)为

    a2)另一个有溢出的情况

    • 实际价值: t0 = 2 t1 = 5
    • 溢出: t0 = 2 t1 = -3
    • t0 < t1==> 2 < -3 - > false
    • t0 - t1 < 0==> 2 - (-3) < 0==> -3 < 0(再次5溢出到-3)为


    所以再次只t0 - t1 < 0给出正确的结果.

    b)没有溢出 t0 - t1将始终等于-3(-delta),因此这将始终给出正确的结果.t0 < t1也会给予正确的回复

    • 实际价值: t0 = -1 t1 = 2
    • t0 < t1==> -1 < 2 - > true
    • t0 - t1 < 0==> -1 - 2 < 0==> -3 < 0 是的
  4. delta = 4结果t0 - t1将始终等于,-4所以它也将是<0.

    溢出的例子
    a1)

    • 实际价值: t0 = 0 t1 = 4
    • 溢出: t0 = 0 t1 = -4
    • t0 < t1==> 0 < -4 - > false
    • t0 - t1 < 0==> 0 - (-4) < 0==> -4 < 0(4溢出到-4)为

    a2)

    • 实际价值: t0 = 1 t1 = 5
    • 溢出: t0 = 1 t1 = -3
    • t0 < t1==> 1 < -4 - > false
    • t0 - t1 < 0==> 1 - (-3) < 0==> -4 < 0(4溢出到-4)为

    所以再次只t0 - t1 < 0给出正确的结果.

    没有溢出的示例显然对于两个测试都是正确的.

  5. delta = 5(及更多)

    a1)溢出
    (最小值tor t0为-1所以让我们从它开始)

    • 实际价值: t0 = -1 t1 = 4
    • 溢出: t0 = -1 t1 = -4
    • t0 < t1==> -1 < -4 - > false
    • t0 - t1 < 0==> -1 - (-4) < 0==> 3 < 0 false

    a2)溢出

    • 实际价值: t0 = 1 t1 = 6
    • 溢出: t0 = 1 t1 = -2
    • t0 < t1==> 1 < -2 - > false
    • t0 - t1 < 0==> 1 - (-2) < 0==> 3 < 0 false 两个测试都失败了

    b1)没有溢出

    • t0 = -4, t1 = 1
    • -4 < 1 真正
    • -4 - 1 < 0==> 3 < 0(-5溢出到3)false

+-------------+-----------------------------+----------------------------+
|  tests if   | delta <= size of half cycle | delta > size of half cycle |
| t0 is less  |-----------------------------|----------------------------|
|  than t1    |  overflow  |  no overflow   | overflow  |  no overflow   |
|-------------|------------|----------------|-----------|----------------|
|   t0 < t1   |      -     |       +        |     -     |       +        |
|-------------|------------|----------------|-----------|----------------|
| t0 - t1 < 0 |      +     |       +        |     -     |       +        |
|-------------|------------|----------------|-----------|----------------|
| t0 - t1 > 0 |      -     |       -        |     +     |       -        |
+-------------+------------+----------------+-----------+----------------+
Run Code Online (Sandbox Code Playgroud)