为什么要使用t1-t0<;0,而不是t1<;t0,在Java中使用System.nanoTime()时
当我阅读Java中的System.nanoTime()API时。我发现这句话: 应该使用t1-t0<0,而不是t1为什么要使用t1-t0<;0,而不是t1<;t0,在Java中使用System.nanoTime()时,java,math,comparison,overflow,Java,Math,Comparison,Overflow,当我阅读Java中的System.nanoTime()API时。我发现这句话: 应该使用t1-t0
long t0 = System.nanoTime();
...
long t1 = System.nanoTime();
应该使用t1-t0<0,而不是t1t1-t0<0
是防止溢出的更好方法
因为我从另一个线程读到,A
比A-B<0
更可取
这两件事产生了矛盾。纳米时间不是一个“实时”时间,它只是一个计数器,当某个未指定的事件发生时(可能是计算机启动时),它从某个未指定的数字开始递增 它将溢出,并在某个点变为负值。如果您的
t0
正好在溢出之前(即非常大的正值),而t1
正好在溢出之后(非常大的负值),则t1
(即您的条件是错误的,因为t1
发生在t0
之后)
但是,如果你说t1-t0<0
,那么神奇的是,由于相同的溢出(未流动)原因(非常大的负减去非常大的正将下溢),结果将是t1在t0
之后的纳秒数。。。。。而且是对的
在这种情况下,两个错误真的是正确的 这句话实际上是:
由于数字溢出,连续调用的差异超过大约292年(2^63纳秒)将无法准确计算经过的时间
如果t0和t1相隔292年测量,则会出现数值溢出。否则,比较法或减法都可以正常工作。使用任何方法。在最近的290年内不会有什么不同。
你的程序(甚至Java本身)不会活这么久。
t0-t1<0
比t0
更好,因为我们可以确定实际值的差异(溢出前)不会超过包含所有可能值的集的一半或大小。纳秒大约为292年(纳秒存储在long中,一半的
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, ..
让我们看看t0-t1<0
和t0
对于差值将大于或不会大于4的值(循环大小的一半,-4是最小值,这意味着它可以是计算增量的最小结果)的行为。请注意,当t1
溢出时,只有t0-t1<0
才会给出正确的结果
- 实际值:
t0=3
t1=4
- 溢出:
t0=3
t1=-4
==>t0
->false3<-4
==>t0-t1<0
=>3-(-4)<0
(7次溢出到-1)true-1<0
t0-t1<0
我们得到了正确的结果,尽管可能是由于溢出
,t0=2
t1=3
true2<3
==>2-3<0
true-1<0
,t0=-4
t1=-3
true-4<-3
==>-4-(-3)<0
true-1<0
t0
和t0-t1<0
测试的正确结果(t0-t1
始终为-1
)- 实际值:
t0=3
t1=6
- 溢出:
t0=3
t1=-2
==>t0
->false3<-2
==>t0-t1<0
=>3-(-2)<0
(5次溢出到-3)true-3<0
- 实际值:
t0=2
t1=5
- 溢出:
t0=2
t1=-3
==>t0
->false2<-3
==>t0-t1<0
=>2-(-3)<0
(再次5次溢出到-3)true-3<0
同样,只有
t0-t1<0
给出了正确的结果
b) 没有溢出t0-t1
将始终等于-3
(-delta),因此这将始终给出正确的结果<代码>t0- 实际值:
t0=-1
t1=2
==>t0
->true-1<2
==>t0-t1<0
=>-1-2<0
true-3<0
+-------------+-----------------------------+----------------------------+ | 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 | - | - | + | - | +-------------+------------+----------------+-----------+----------------+