认识异或运算

1.什么是异或运算

异或运算是位运算的一种,符号为:^
运算规则为:相同为0,不同为1
例如
在这里插入图片描述
性质:

N ^ 0 = N
N ^ N = 0
A ^ B = B ^ A
(A ^ B) ^ C = A ^ (B ^ C)
  • N ^ 0 = N
public class XorOperation {
    public static void main(String[] args) {
        System.out.println(zeroXorNonZeroNum(5)); // 5
    }

    // 0与非零数异或
    private static int zeroXorNonZeroNum(int n) {
        return 0 ^ n;
    }
}

位与位异或,相同为0,不相同为1,所以b的结果为5


  • N ^ N = 0
public class XorOperation {
    public static void main(String[] args) {
        System.out.println(nonZeroXorSelf(5)); // 0
    }
    
    // 非零数与自身异或
    private static int nonZeroXorSelf(int n) {
        return n ^ n;
    }
}

两个相同的数,二进制都是一样的,所以在位与位进行异或的时候都相同,每一位的结果都是0


  • 交换律
public class XorOperation {
    public static void main(String[] args) {
        System.out.println(twoNonZeroNumXor(3, 8)); // 11
        System.out.println(twoNonZeroNumXor(8, 3)); // 11
    }

    // 两个非零数异或运算
    private static int twoNonZeroNumXor(int a, int b) {
        return a ^ b;
    }
}

因为异或是位与位进行计算的,所以异或的顺序不重要,结果是一样的


  • 结合律
int a = 2;
int b = 5;
int c = 4;
int d = (a ^ b) ^ c;
int e = a ^ b ^ c;
int f = a ^ (b ^ c);
System.out.println(d == e);	//true
System.out.println(f == e);	//true

通过交换律得知,异或的顺序不会影响结果,所以在某一些数先异或,再异或另个数的时候,也不会影响结果,这就是异或满足结合律

2.异或运算的本质

异或运算的本质是不带进位的加法

2.1 2阶异或运算

来看一个例子:
(10进制)5 = (二进制)00000101 (10进制)6 = (二进制)00000110
5 ^ 6 计算过程如下:
在这里插入图片描述
相同为0,不同为1

2.3 3阶异或运算

来看一个例子:
(10进制)5 = (三进制)00000012 (10进制)6 = (三进制)00000020
5 ^ 6 计算过程如下:
在这里插入图片描述
2 ^ 0 = 2,1 ^ 2 = 0

2.4 4阶异或运算

来看一个例子:
(10进制)5 = (四进制)00000011 (10进制)6 = (四进制)00000012
5 ^ 6 计算过程如下:
在这里插入图片描述
1 ^ 2 = 3,1 ^ 1 = 2

3.异或运算的应用

3.1 交换两个变量的值

代码如下:

public class XorOperation {
    public static void main(String[] args) {
        int a = 4;
        int b = 5;
        System.out.println("==== exchange before ====");
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        
        a = a ^ b;
        b = a ^ b;
        a = a ^ b;
        System.out.println("==== exchange after ====");
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }
}

运行结果

==== exchange before ====
a = 4
b = 5
==== exchange after ====
a = 5
b = 4

3.2 如何把一个数字x最右侧那个1拿出来,变成00…10…的格式

代码如下

public class XorOperation {
    private static int getRightOne4Num(int n) {
        return n & (~n + 1);
    }
    
	public static void main(String[] args) {
        System.out.println(getRightOne4Num(5));
    }
}

运行结果

1

举一个例子:
比如取出5的最右侧为1的二进制数字
在这里插入图片描述

3.3 统计一个二进制数中1出现的次数

代码如下

public class XorOperation {
	public static int countBinaryOne(int n) {
        int count = 0;
        while (n != 0) {
            int rightOne = n & (~n + 1);
            count++;
            n ^= rightOne;
        }
        return count;
    }

    public static void main(String[] args) {
        System.out.println(countBinaryOne(5));
    }
}

运行结果

2

3.4 在一个数组中,只有一种数,出现奇数次,如何把它找出来

代码如下

public class XorOperation {
// 数组中,只有一种数,出现奇数次
    public static void printOddTimesNum1(int[] arr) {
        int eor = 0;
        for (int i = 0; i < arr.length; i++) {
            eor ^= arr[i];
        }
        System.out.println(eor);
    }
    public static void main(String[] args) {
        printOddTimesNum1(new int[]{1, 2, 1, 1, 4, 5, 4, 5, 2});
    }
}

运行结果

1

3.5 在一个数组中,有两种数,出现奇数,如何把这两种数找出来

代码如下:

public class XorOperation {
	public static void printOddTimesNum2(int[] arr) {
        int eor = 0;
        for (int i = 0; i < arr.length; i++) {
            eor ^= arr[i];
        }
        int rightOne = eor & (~eor + 1);// 取出最右边的1
        int onlyOne = 0;
        for (int i = 0; i < arr.length; i++) {
            if ((arr[i] & rightOne) != 0) {
                onlyOne ^= arr[i];
            }
        }
        System.out.println(onlyOne + " " + (eor ^ onlyOne));
    }
	public static void main(String[] args) {
        printOddTimesNum2(new int[]{1, 2, 1, 1, 4, 5, 4, 5});
    }

运行结果:

1 2

4.总结

  • 异或运算的本质是k阶不带进位的加法运算
  • 偶数个k异或运算的结果为0
  • 奇数个k异或运算的结果为k本身
  • x异或0=x,x异或x=0,异或运算不考虑顺序
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 本次实验旨在通过实际操作和实验验证,掌握八位运算器的数据传输格式,以及运算功能发生器和进位控制的组合功能。在完成算术、逻辑和移位运算实验的过程中,我们需要熟悉ALU运算控制位的运用。 在实验过程中,我们首先了解了八位运算器的数据传输格式,并学习了相关的运算控制位的含义和使用方法。然后,我们进行了算术运算、逻辑运算和移位运算的实验,通过输入不同的数据和设置不同的运算控制位,观察运算结果是否符合预期。 在实验中,我们还发现了一些常见的问题和注意事项。例如,需要注意数据传输的长度和方向,以及运算控制位的设置顺序和正确性。此外,在进行逻辑运算时,需要注意各个位之间的关系和运算规则,以免出现错误的结果。 总的来说,本次实验让我们更加深入地了解了八位运算器的工作原理和使用方法,同时也提高了我们的实验操作能力和问题解决能力。 ### 回答2: 通过本次实验,我们成功完成了八位运算器的实验,达到了实验目的。在实验过程中,我们掌握了八位运算器的数据传输格式,了解了运算功能发生器及进位控制的组合功能。 在实验中,我们完成了算术、逻辑和移位运算。通过设置ALU运算控制位,我们可以根据需要进行不同的运算操作。我们成功实现了加法、减法、与门、或门、非门、左移和右移等运算。 在实验过程中,我们需要注意设置好运算控制位,确保正确选择所需的运算操作。另外,在进行移位运算时,需要考虑好移位的方向和位数,避免运算结果出错。 本次实验中,我们掌握了ALU运算控制位的使用方法,了解了八位运算器的工作原理。通过实验,加深对计算机运算器的理解和掌握。 在实验中,我们遇到了一些问题,在设置运算控制位和确定运算结果时出现了一些困惑。我们通过仔细观察实验装置的工作状态,查阅资料,和同学们的讨论交流,最终成功解决了问题。 通过本次实验,我们认识到了运算器在计算机系统中的重要性。运算器是计算机的核心组成部分,负责进行各种算术和逻辑运算。掌握了运算器的工作原理和使用方法,对于理解和掌握计算机系统的工作机制具有重要意义。 总之,本次实验让我们更加熟悉了运算器的操作和原理,提高了我们的实验能力和动手能力。通过实验,我们对计算机系统的运算器有了更深入的理解,为今后的学习和研究打下了坚实的基础。 ### 回答3: 本次实验是运算器实验,主要目的是掌握八位运算器的数据传输格式,并验证运算功能发生器及进位控制的组合功能。在实验中,我按照要求完成了算术、逻辑、移位运算实验,并熟悉了ALU运算控制位的使用。 在实验过程中,首先我了解了八位运算器的数据传输格式,包括数据输入和数据输出的方式。然后我通过连接实验设备,按照实验手册给出的运算控制位进行设置,实现了算术运算、逻辑运算和移位运算。在每次实验前,我先仔细阅读了相关的实验原理和步骤,确保操作正确。 在算术运算实验中,我成功实现了加法和减法运算,并观察到了进位和借位的产生与传递。在逻辑运算实验中,我实现了与、或、非和异或运算,并验证了结果的正确性。在移位运算实验中,我实现了左移和右移操作,通过改变数据和移位控制位的设置,可以得到不同的移位结果。 通过本次实验,我深刻认识到了运算器的工作原理和控制方式。同时,我也意识到在实际应用中,合理设置运算控制位非常重要,可以实现不同的运算功能。此外,我还了解到了如何利用运算器进行逻辑运算和移位运算,这对于实际电路设计和数据处理都具有重要意义。 总之,本次实验让我对八位运算器有了更深入的了解,并成功掌握了其数据传输格式和运算功能。通过实践操作,我提高了对ALU运算控制位的运用能力,对于将来的学习和工作都大有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值