int 类型是java中常见的基本类型。但是最近我发现在int的使用有一些不易掌握的特性,在不深入了解内部原理情况下,容易判断错误。
1、Integer 真是引用类型吗
众所周知,Integer作为int包装类是引用类型。但是请看下面这段代码,最后输出是true。
Integer a=127;
Integer b=127;
System.out.println(a==b);
2、-2147483648
在数学意义上,绝对值是非负数。但下面代码取绝对值的输出还是-2147483648
int tmp=Math.abs(-2147483648);
System.out.println(tmp);
以上问题涉及两个知识点
- IntegerCache
- 计算机加减法运算(原码、反码、补码)
把两个知识点展开看
- IntegerCache
JSL规定IntegerCache为Integer类的缓存类,默认缓存了-128~127的Integer 值,如遇到[-128,127]范围的值需要转换为Integer时会直接从IntegerCache中获取。同时,我们可以通过设置java.lang.Integer.IntegerCache.high来设置缓存最大值
-Djava.lang.Integer.IntegerCache.high=255
- 计算机加减法(原码、反码、补码)
- 原码、反码和补码
我们都知道计算机中的数值使用二进制表示的,与计算机存储结构有关。假定我们的计算机为4位机(一个Byte),那么十进制1在转为二进制就是0001。此外,我们还需要考虑一个问题那就是符合,负数我们怎么表示,我们将第一位设置为符号位(0为正数+,1为负数-)。这样我们的原码就出来了。
| 十进制 | 4位二进制原码 |
|---|---|
| 1 | 0001 |
| -2 | 1010 |
考虑到计算机特性,运算方式越简单越好。我们考虑将减法转换成加法,这就引入了反码。正数的反码还是正数,负数的反码是除符号位外,全部取反。一个二进制数(原码)减去另一个二进制数(原码)就转换为一个二进制数反码加上另一个二进制数的反码。
| 十进制 | 原码 | 反码 |
|---|---|---|
| 1 | 0001 | 0001 |
| -1 | 1000 | 1111 |
| 二进制结果 | 1000 | |
| 十进制结果 | -0 |
| 十进制 | 原码 | 反码 |
|---|---|---|
| 1 | 0001 | 0001 |
| -2 | 1010 | 1101 |
| 二进制结果 | 1110 | |
| 二进制结果求反 | 1001 | |
| 十进制结果 | -1 |
如上图所示反码的引入,虽然解决了加法变减法的转换,却引入负零和循环进位等复杂计算逻辑。
补码的出现则进一步简化了运算,补码只需要进行简单加法,舍弃进位即可得到结果。
| 十进制 | 原码 | 反码 | 补码 |
|---|---|---|---|
| 1 | 0001 | 0001 | 0001 |
| -2 | 1010 | 1101 | 1110 |
| 二进制结果 | 1111 | ||
| 二进制结果反码 | 1110 | ||
| 二制结果 | 1001(-1) |
- Integer的边界问题
通过引入补码,计算机的加减运算简化为了简单的相加,数值在计算机内存中也以补码的形式存储。
原码 => 补码: 取反加一(符号位不参加运算)
补码=> 原码: 取反加一(一般情况下,符号位不参加运算)
在补码中,1000不再表示负零,而是-8。所以给定n位存储长度,可以表达数值范围为-2的n次方到2的(n-1)次方。
由补码求其绝对值补码的公式为,补码取反加一(包括符号位)
以下为给定4位长度的二进制数求绝对值。
| 十进制 | 原码 | 补码 | 其绝对值原码 |
|---|---|---|---|
| -1 | 1001 | 1111 | 0001 |
| -8 | 1000 | 1000 | 1000 |
-2147483648为int 给定32位最小的值,与-8类似,绝对值与其本身一致。
最后总结
在计算机数值计算时,需要考虑数值精度是否一致和是否有溢出。
- 数值超过数据类型支持最大精度溢出后,计算结果出错(不仅仅是丢失进度)
- 数值计算,结果精度就最大的精度
- Integer计算需要考虑是否有缓存
本文探讨了Java中Integer类型的特性,包括IntegerCache的缓存机制,导致127及其以下值的比较返回true的情况。同时,解释了计算机中的加减法运算,特别是补码在处理负数和溢出时的角色。文章通过实例展示了-2147483648作为int最小值,在取绝对值时保持不变的原因。强调在编程中理解这些基础知识对于避免错误和提高效率的重要性。
808

被折叠的 条评论
为什么被折叠?



