if(a – b <0)和if(a

问题:

我正在阅读Java的ArrayList源代码,并注意到在if语句中的一些比较。
在Java 7中,方法grow(int)使用

if (newCapacity - minCapacity < 0)
    newCapacity = minCapacity;
&#91;/code&#93;
在Java 6中,<code>grow</code>不存在。然而,方法<a href="http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b27/java/util/ArrayList.java#ArrayList.ensureCapacity%28int%29"><code>ensureCapacity(int)</code></a>使用

if (newCapacity < minCapacity)
    newCapacity = minCapacity;
&#91;/code&#93;
改变背后的原因是什么?这是一个性能问题还是一种风格?
我可以想象,与零比较更快,但执行完全减法只是为了检查是否负面似乎对我有点过度。同样在字节码方面,这将涉及两个指令(<code>ISUB</code>和<code>IF_ICMPGE</code>)而不是一个(<code>IFGE</code>)。

<h4>回答:</h4>
 <code>a &lt; b</code>和<code>a - b &lt; 0</code>可能意味着两个不同的东西。请考虑以下代码:

int a = Integer.MAX_VALUE;
int b = Integer.MIN_VALUE;
if (a < b) {
    System.out.println("a < b");
}
if (a - b < 0) {
    System.out.println("a - b < 0");
}
&#91;/code&#93;
运行时,这只会打印<code>a - b &lt; 0</code>。发生什么是<code>a &lt; b</code>显然是错误的,但<code>a - b</code>溢出并成为<code>-1</code>,这是负数。
现在,已经说过了,这个数组的长度真的接近<code>Integer.MAX_VALUE</code>。 <code>ArrayList</code>中的代码如下所示:

int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
    newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
    newCapacity = hugeCapacity(minCapacity);

 oldCapacity真的接近Integer.MAX_VALUE,所以newCapacity(即oldCapacity + 0.5 * oldCapacity)可能会溢出并成为Integer.MIN_VALUE(即消极)。然后,将minCapacity underflows减去一个正数。
此检查确保if未被执行。如果代码写为if (newCapacity < minCapacity),则在这种情况下true(因为newCapacity为负数),所以newCapacity将被强制为minCapacity而不管oldCapacity
这个溢出的情况是由下一个if来处理的。当newCapacity溢出时,这将是trueMAX_ARRAY_SIZE定义为Integer.MAX_VALUE - 8Integer.MIN_VALUE - (Integer.MAX_VALUE - 8) > 0true。因此,newCapacity正确处理:hugeCapacity方法返回MAX_ARRAY_SIZEInteger.MAX_VALUE
注意:这是这个方法所说的// overflow-conscious code评论。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Difference between if (a - b < 0) and if (a < b)

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

78 − 76 =