
本质都是以二进制码存储。计算机中的没法直接做减法的,它的减法是通过加法来实现的。你也许会说,现实世界中所有的减法也可以当成加法的,减去一个数,可以看作加上这个数的相反数。当然没错,但是前提是要先有负数的概念。这就为什么不得不引入一个该死的符号位。
1. 而且从硬件的角度上看,只有正数加负数才算减法。
2. 正数与正数相加,负数与负数相加,其实都可以通过加法器直接相加。
2. 正数位移运算
<<:左移>>:右移>>>:无符号右移
public class test {
public static void main(String[] args) {
System.out.println(3 << 1); // 6
System.out.println(3 >> 1); // 1
System.out.println(3 >>> 1); // 1
System.out.println(-3 << 1); // -6
System.out.println(-3 >> 1); // -2
System.out.println(-2 >>> 1); // 2147483647
}
}

3 >> 1
:十进制“3”转换成二进制为“00000000 00000000 00000000 00000011”,再将二进制右移一位,低位丢弃,高位补0,所以结果为“00000000 00000000 00000000 00000001”,换算成十进制则为“1”3 << 1
:十进制“3”转换成二进制为“00000000 00000000 00000000 00000011”,再将二进制左移一位,高位丢弃,低位补0,所以结果为“00000000 00000000 00000000 00000110”,换算成十进制则为“6”对于这两种情况非常好理解,那什么是无符号右移,以及负数是怎么运算的呢?
我们先来看-3 << 1
与-3 >> 1
,这两个负数的左移与右移操作其实和正数类似,都是先将十进制数转换成二进制数,再将二进制数进行移动,所以现在的关键是负数如何用二进制数进行表示。
3. 原码、反码、补码
1. 原码
-111 1111 ~ +111 1111,换成十进制就是
-127 ~ 127。
2. 反码
5-3=2,其实可以转换成
5+(-3)=2,这就表示减法可以用加法表示,而乘法是加法的累积,除法是减法的累积,所以在计算机中只要有加法就够了。
5-3举例。
5 - 3等于
5 + (-3)5-3
= 5+(-3)
= 0000 0101(反码) + 1111 1100(反码)
= 0000 0001(反码)
= 0000 0001(原码)
= 1

1-1
= 1+(-1)
= 0000 0001(反码) + 1111 1110(反码)
= 1111 1111(反码)
= 1000 0000(原码)
= -0
0+0
= 0000 0000(反码) + 0000 0000(反码)
= 0000 0000(反码)
= 0000 0000(原码)
= 0
3. 补码
| 0000 0011 | |||
5-3
= 5+(-3)
= 0000 0101(补码) + 1111 1101(补码)
= 0000 0010(补码)
= 0000 0010(原码)
= 2

1-1
= 1+(-1)
= 0000 0001(补码) + 1111 1111(补码)
= 0000 0000(补码)
= 0000 0000(原码)
= 0
0+0
= 0000 0000(补码) + 0000 0000(补码)
= 0000 0000(补码)
= 0000 0000(原码)
= 0
正数的原码、反码、补码是一致的;
负数的补码是反码加1,反码是对原码按位取反,只是最高位(符号位)不变;
计算机数字运算均是基于补码的。
补码有啥好?


4. 负数位移运算
-3 << 1与
-3 >> 1。
10000000 00000000 00000000 0000001111111111 11111111 11111111 1111110011111111 11111111 11111111 11111101-3 << 1,表示-3的补码左移一位后为
11111111 11111111 11111111 11111010,该补码对应的反码为
11111111 11111111 11111111 11111010
- 1
= 11111111 11111111 11111111 11111001
10000000 00000000 00000000 00000110,表示-6。
-3 << 1 = -6。
-3 >> 1是一样的计算方法,这里就不演示了。
5. 无符号右移
-2 >>> 1。
10000000 00000000 00000000 0000001011111111 11111111 11111111 1111110111111111 11111111 11111111 1111111001111111 11111111 11111111 1111111101111111 11111111 11111111 11111111(因为现在的符号位为0,表示正数,正数的原、反、补码都相同)
-2 >>> 1 = 21474836476. 总结


文章转载自五角钱的程序员,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




