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值
Run Code Online (Sandbox Code Playgroud)long t0 = System.nanoTime(); ... long t1 = System.nanoTime();
一个应该使用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
....并且是对的.
在这种情况下,两个错误确实是正确的!
t0 - t1 < 0
t0 < 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 < 0
且t0 < t1
将会表现为不会大于4的值(循环大小的一半,-4是最小值,这意味着它可以是计算delta的最小结果).请注意,只有t0 - t1 < 0
在t1
溢出时才会给出正确的结果
delta = 1,溢出值越大(注意:我们不会使较小的值溢出,因为这意味着两个值都处于同一个周期,因此计算将与没有溢出的情况相同)
t0 = 3
t1 = 4
t0 = 3
t1 = -4
t0 < t1
==> 3 < -4
- > falset0 - t1 < 0
==> 3 - (-4) < 0
==> -1 < 0
(7溢出到-1)为真所以仅适用于t0 - t1 < 0
我们得到正确的结果,尽管或许由于溢出.
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 < t1
和t0 - t1 < 0
测试的正确结果(t0 - t1
将始终-1
)
delta = 3(几乎是周期的一半)
a1)溢出更大的价值
t0 = 3
t1 = 6
t0 = 3
t1 = -2
t0 < t1
==> 3 < -2
- > falset0 - t1 < 0
==> 3 - (-2) < 0
==> -3 < 0
(5溢出到-3)为真a2)另一个有溢出的情况
t0 = 2
t1 = 5
t0 = 2
t1 = -3
t0 < t1
==> 2 < -3
- > falset0 - 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
- > truet0 - t1 < 0
==> -1 - 2 < 0
==> -3 < 0
是的delta = 4结果t0 - t1
将始终等于,-4
所以它也将是<0
.
溢出的例子
a1)
t0 = 0
t1 = 4
t0 = 0
t1 = -4
t0 < t1
==> 0 < -4
- > falset0 - t1 < 0
==> 0 - (-4) < 0
==> -4 < 0
(4溢出到-4)为真a2)
t0 = 1
t1 = 5
t0 = 1
t1 = -3
t0 < t1
==> 1 < -4
- > falset0 - t1 < 0
==> 1 - (-3) < 0
==> -4 < 0
(4溢出到-4)为真 所以再次只t0 - t1 < 0
给出正确的结果.
没有溢出的示例显然对于两个测试都是正确的.
delta = 5(及更多)
a1)溢出
(最小值tor t0为-1所以让我们从它开始)
t0 = -1
t1 = 4
t0 = -1
t1 = -4
t0 < t1
==> -1 < -4
- > falset0 - t1 < 0
==> -1 - (-4) < 0
==> 3 < 0
false a2)溢出
t0 = 1
t1 = 6
t0 = 1
t1 = -2
t0 < t1
==> 1 < -2
- > falset0 - 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)
归档时间: |
|
查看次数: |
1235 次 |
最近记录: |