if(a-b <0)和if(a <b)之间的差异
我正在阅读Java的ArrayList
源代码,并注意到if语句中的一些比较。
在Java
7中,该方法grow(int)
使用
if (newCapacity - minCapacity < 0) newCapacity = minCapacity;
在Java 6
grow
中不存在。ensureCapacity(int)
但是该方法使用
if (newCapacity < minCapacity) newCapacity = minCapacity;
更改背后的原因是什么?是性能问题还是样式?
我可以想象与零进行比较会更快,但是对我来说,执行完全减法只是为了检查它是否为负似乎有点过大。同样在字节码方面,这将涉及两个指令(ISUB
和IF_ICMPGE
)而不是一个指令(IFGE
)。
回答:
a < b
并且a - b < 0
可能意味着两个不同的东西。考虑以下代码:
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");
}
运行时,将仅打印a - b < 0
。发生的事情a < b
显然是错误的,但是a - b
溢出并变为-1
,这是负面的。
话虽如此,请考虑一下数组的长度确实接近Integer.MAX_VALUE
。中的代码ArrayList
如下所示:
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
下溢 相减回正数。
此检查确保if
不会执行。如果代码编写为if (newCapacity <
minCapacity),则true
在这种情况下(由于newCapacity
为负)newCapacity
将被强制执行,minCapacity
而与无关oldCapacity
。
此溢出情况由下一个if处理。当newCapacity
已经溢出,这将是true
:MAX_ARRAY_SIZE
被定义为Integer.MAX_VALUE
- 8和Integer.MIN_VALUE - (Integer.MAX_VALUE - 8) >
0的true
。将newCapacity
因此被正确地处理:hugeCapacity
方法返回MAX_ARRAY_SIZE
或Integer.MAX_VALUE
。
注意:这就是// overflow-conscious code
此方法中的注释。
以上是 if(a-b <0)和if(a <b)之间的差异 的全部内容, 来源链接: utcz.com/qa/420215.html