/**
* 符号转换操作 主要针对
* & 逻辑与
* | 逻辑或
* ^ 逻辑异或
* ~ 取反
* << 有符号左移
* >> 有符号右移
* >>> 无符号右移
*
* @Author: xiaofeifei
* @Date: 2021/1/22 10:32
*/
public class SymbolTransferDemo {
public static void main(String[] args) {
int a = 1;
int b = 3;
int d = -2;
// 1. 逻辑与
logicAnd(a, b, d);
// 2. 逻辑或
logicOr(a, b, d);
// 3. 逻辑异或
logicXOR(a, b, d);
// 4. 取反
logicNegate(a, b, d);
// 5. 有符号左移
symbolShiftLeft(a, b, d);
// 6. 有符号右移
symbolShiftRight(a, b, d);
// 7. 无符号右移
noSymbolShiftRight(a, b, d);
}
private static void noSymbolShiftRight(int a, int b, int d) {
// 无符号右移 高位补0
int c;
c = a >>> 2;
// a的补码: 0000 0000 0000 0000 0000 0000 0000 0001
//a无符号右移:0000 0000 0000 0000 0000 0000 0000 0000 => 0
System.out.println("正数无符号右移2位 = " + c);
d = -4;
c = d >>> 2;
// 负数的无符号右移 高位补0
// d的补码: 1111 1111 1111 1111 1111 1111 1111 1100
// d有符号右移: 0011 1111 1111 1111 1111 1111 1111 1111 => 为正数 1073741823
System.out.println("负数无符号右移2位 = " + c);
}
private static void symbolShiftRight(int a, int b, int d) {
// 有符号右移 如果为正数 则高位补0 如果为负数 则高位补1
int c;
c = a >> 2;
// a的补码: 0000 0000 0000 0000 0000 0000 0000 0001
//a有符号右移:0000 0000 0000 0000 0000 0000 0000 0000 => 0 最高位正数补0 负数补1
System.out.println("正数有符号右移2位 = " + c);
d = -4;
c = d >> 2;
// 负数的有符号右移 高位补1
// d的补码: 1111 1111 1111 1111 1111 1111 1111 1100
// d有符号右移: 1111 1111 1111 1111 1111 1111 1111 1111 => 为负数 => 最高位正数补0 负数补1
// d结果为: 1000 0000 0000 0000 0000 0000 0000 0001 => -1
System.out.println("负数有符号右移2位 = " + c);
}
private static void symbolShiftLeft(int a, int b, int d) {
int c;
c = a << 2;
// a的补码: 0000 0000 0000 0000 0000 0000 0000 0001
//a有符号左移:0000 0000 0000 0000 0000 0000 0000 0100 => 4 最高位正数补0 负数补1
System.out.println("正数有符号左移2位 = " + c);
c = d << 2;
// d的补码: 1111 1111 1111 1111 1111 1111 1111 1110
// d左移: 1111 1111 1111 1111 1111 1111 1111 1000 => 为负数 => 最高位正数补0 负数补1
// 1000 0000 0000 0000 0000 0000 0000 1000 => -8
System.out.println("负数有符号左移2位 = " + c);
}
private static void logicNegate(int a, int b, int d) {
int c;
c = ~a;
// a的补码: 0000 0000 0000 0000 0000 0000 0000 0001
// 取反: 1111 1111 1111 1111 1111 1111 1111 1110 => 为负数 转化为原码
// 1000 0000 0000 0000 0000 0000 0000 0010 => -2
System.out.println("正数取反 = " + c);
c = ~d;
// d的补码: 1111 1111 1111 1111 1111 1111 1111 1110
// ~取反: 0000 0000 0000 0000 0000 0000 0000 0001 => 为正数 结果为1
System.out.println("负数取反 = " + c);
}
private static void logicXOR(int a, int b, int d) {
int c;
c = a ^ b;
// a => 0000 0001
// b => 0000 0011
// c => a ^ b => 0000 0010 => 2
System.out.println("逻辑异或 = " + c);
// 负数测试
c = b ^ d;
// 负数是以补码的形式参与计算机计算
// d => 1000 0000 0000 0000 0000 0000 0000 0010 取反 + 1为:
// 1111 1111 1111 1111 1111 1111 1111 1110
// 0000 0000 0000 0000 0000 0000 0000 0011
//^ 1111 1111 1111 1111 1111 1111 1111 1101 => 结果为负 转换为原码
// 1000 0000 0000 0000 0000 0000 0000 0011 => -3
System.out.println("负数和正数逻辑异或 = " + c);
// 全负数测试
int e = -4;
c = e ^ d;
// d补码: 1111 1111 1111 1111 1111 1111 1111 1110
// e补码: 1111 1111 1111 1111 1111 1111 1111 1100
// 进行^: 0000 0000 0000 0000 0000 0000 0000 0010 => 结果为正数 原码就是补码 2
System.out.println("负数和负数逻辑异或 = " + c);
}
private static void logicOr(int a, int b, int d) {
// 2. 逻辑或
int c;
c = a | b;
// a => 0000 0001
// b => 0000 0011
// c => a & b => 0000 00011 => 3
System.out.println("逻辑或 = " + c);
// 负数测试
c = b | d;
// 因为负数计算机是以补码的形式保存 -2是原码(展示为这个数据) 因此我们需要先转换成补码参与计算 d => -2取反 + 1 真实的计算中也是以补码的形式进行计算
// d => 1000 0000 0000 0000 0000 0000 0000 0010 取反 + 1为:
// 1111 1111 1111 1111 1111 1111 1111 1110
// 0000 0000 0000 0000 0000 0000 0000 0011
//| 1111 1111 1111 1111 1111 1111 1111 1111 => 因为最高位为1,所以结果为负数,这个结果为补码 我们需要转换成我们所理解的原码
// 原码 = (补码 - 1)取反=> 1111 1111 1111 1111 1111 1111 1111 1110
// 取反 => 1000 0000 0000 0000 0000 0000 0000 0001 => -1
System.out.println("负数和正数逻辑或 = " + c);
}
private static void logicAnd(int a, int b, int d) {
// 1. 逻辑与
// a => 0000 0001
// b => 0000 0011
// c => a & b => 0000 0001 => 1
int c = a & b;
System.out.println("逻辑与 = " + c);
// 负数测试
c = b & d;
// 因为负数是以补码的形式保存 d => -2取反 + 1
// d => 1000 0000 0000 0000 0000 0000 0000 0010 取反 + 1为:
// 1111 1111 1111 1111 1111 1111 1111 1110
// 0000 0000 0000 0000 0000 0000 0000 0011
//& 0000 0000 0000 0000 0000 0000 0000 0010 => 2
System.out.println("负数和正数逻辑与 = " + c);
}
}