假如,我们要用Math.abs对一个nteger取绝对值的时候,如果用如下方式:
Math .abs(orderId.hashCode());
得到的结果可能是个负数。原因要从Integer的取值范围说起,int的取值范围是-2^31—— (2^31)-1,即-2147483648 至 2147483647。
那么,当我们使用abs取绝对值时候,想要取得-2147483648的绝对值,那应该是2147483648。但是2147483648大于了2147483647,即超过了int的取值范围。这时候就会发生越界。
2147483647用 进制的 码表示是: 01111111 11111111 11111111 11111111
这个数 +1 得到: 1000000 00000000 00000000 0000000
这个二进制就是-2147483648的补码。
虽然,这种情况发生的概率很低,只有当要取绝对值的数字是-2147483648的时候,得到的数字还是个负数。
那么,如何解决这个问题呢?
既然是因为越界了导致最终结果变成负数,那就解决越界的问题就行了,那就是在取绝对值之前,把这个int类型转成long类型,这样就不会出现越界了。
如,前面我们取值逻辑修改为:
Math.abs((long)orderId.hashCode());
大家可以执行下以下代码:
public static void main(String[] args) {
system.out.println(Math.abs((long)Integer .MIN VALUE));
}
得到的结果就是:
Java中的整型主要包含byte、short、int和long这四种,表示的数字范围也是从小到大的,之所以表示范围不同主要和他们存储数据时所占的字节数有关。
先来个简单的科普,1字节=8位 (bit) 。java中的整型属于有符号数。
先来看计算中8bit可以表示的数字:
最小值: 10000000 (-128) (-2^7) 最大值: 01111111 (127)(2^7-1)
整型的这几个类型中:
上面说过了,整型中,每个类型都有一定的表示范围,但是,在程序中有些计算会导致超出表示范围,即溢出。如以下代码:
int i = IntegerMAX VALUE;
int j = Integer.MAX VALUE;
int k = i + j;
System.out.println("i (" + i+")+j(" +j+") = k(" + k +")");
输出结果: i(2147483647) +j(2147483647) = k (-2)
这就是发生了溢出,溢出的时候并不会抛异常,也没有任何提示。所以,在程序中,使用同类型的数据进行运算的时候,一定要注意数据溢出的问题。