zoukankan      html  css  js  c++  java
  • 异或

      在逻辑学中,逻辑算符异或(exclusive or)是对两个运算元的一种逻辑析取类型,符号为 ^ 或 XOR 或 ⊕(编程语言中常用^)。但与一般的逻辑或不同,异或算符的值为真仅当两个运算元中恰有一个的值为真,而另外一个的值为非真。转化为命题,就是:“两者的值不同。”或“有且仅有一个为真。”

    定义:

    1 ⊕ 1 = 0

    0 ⊕ 0 = 0

    1 ⊕ 0 = 1

    0 ⊕ 1 = 1

    真值表:

    Y

    B = 0

    B = 1

    A = 0

    0

    1

    A = 1

    1

    0

    表达式:

    Y = A’ & B | A & B’

    (注意:以下的否全部使用符号')

    根据定义我们很容易获得异或两个特性:

    恒等律:X ⊕ 0 = X 归零律:X ⊕ X = 0

    然后我们使用真值表可以证明:

    (1)交换律

    A ⊕ B = A' & B | A & B'

    B ⊕ A = B' & A | B & A'

      因为&与和|或两个操作满足交换律,所以:

    A ⊕ B = B ⊕ A

     

    (2)结合律

      (A ⊕ B) ⊕ C

    = (A' & B | A & B') ⊕ C

    = (A' & B | A & B')' & C | (A' & B | A & B') & C '

    = ((A' & B)' & (A & B')')& C | A' & B & C ' | A & B' & C '

    = ((A | B') & (A' | B))& C | A' & B & C ' | A & B' & C '

    = (A & B | A' & B') & C | A' & B & C ' | A & B' & C '

    = A & B & C | A' & B' & C | A' & B & C ' | A & B' & C '

      你可以使用同样推导方法得出(请允许我偷懒一下,数学公式敲起来不容易+_+):

    A ⊕ (B ⊕ C)

    = A & B & C | A' & B' & C | A' & B & C ' | A & B' & C ' 

      证明过程中使用了如下几个方法:

      &与 |或的交换律、分配律和结合律:

    A & B = B & A

    A | B = B | A

    (A & B) & C = A & (B & C)

    (A | B) | C = A | (B | C)

    A & (B | C)= A & B | A & C

    A | B & C = (A | B) & (A | C)

      摩尔定理:

    (A & B)' = A' | B'

    (A | B)' = A' & B'

      结论:

    交换律:A ⊕ B = B ⊕ A 

    结合律:A ⊕ (B ⊕ C) = (A ⊕ B) ⊕ C

      有了归零率和结合律,我们就可以轻松证明:

    自反:A ⊕ B ⊕ B = A ⊕ 0 = A

      可能这些特性会很顺其自然的理解,但是如果你在解决问题的时候,你可能会忘记异或的这些特性,所以适当的应用可以让我们加深对异或的理解;

    A ⊕ 1 = A'

    A ⊕ 0 = A

    A ⊕ A = 0

    A ⊕ A' = 1

     

    (说明:以下的的异或全部使用符号^)

      可能你已经被乱七八糟的公式和演算搞的有点烦了,不就是很简单的异或运算吗?还解释的那么复杂,不要着急,打好了基础,你就站在了巨人的肩膀。

    (1)汇编语言将寄存器置零

    XOR EAX,EAX

     

    (2)异或翻转二进制

    0 ^ 1 = 1

    1 ^ 1 = 0

      翻转10100001的第6位可以将该数与00100000进行按位异或运算;10100001 ^ 00100000 = 10000001

     

    (3)异或判断二进制数中1的数量是奇数还是偶数

      求10100001中1的数量是奇数还是偶数,第一个想到的方法当然是判断最后一位是否为1,让后右移一位,直至变量为0为止。最后判断是奇数还是偶数。

      如果用异或,那把每一位异或,就是:

    1 ^ 0 ^ 1 ^ 0 ^ 0 ^ 0 ^ 0 ^ 1 = 1

      结果为1就是奇数个1,结果为0就是偶数个1。

      这条性质可用于奇偶校验(Parity Check),比如在串口通信过程中,每个字节的数据都计算一个校验位,数据和校验位一起发送出去,这样接收方可以根据校验位粗略地判断接收到的数据是否有误,但如果校验位也错了,那可是一个大问题:)。

     

    (4)RAID5

      校验和恢复主要利用的了异或的特性:if a ^ b = c then a ^ c = b。一个很好的应用实例是RAID5,使用3块磁盘(A、B、C)组成RAID5阵列,当用户写数据时,将数据分成两部分,分别写到磁盘A和磁盘B,A ^ B的结果写到磁盘C;当读取A的数据时,通过B ^ C可以对A的数据做校验,当A盘出错时,通过B ^ C也可以恢复A盘的数据。这就是RAID5的基本原理。

      但RAID5的实现比上述的描述复杂多了,有兴趣的可以上网查一下。

     

    (5)经典题目:不使用其他空间,交换两个值

    a = a ^ b;

    b = a ^ b; //a ^ b ^ b = a ^ 0 = a;

    a = a ^ b;

  • 相关阅读:
    PL/SQL跨库查询数据
    oracle 两个时间相减
    导出Excel格式数据
    Java导出pdf文件数据
    $.ajax相关用法
    oracle 删除掉重复数据只保留一条
    常用Oracle操作语句
    JS请求服务器,并返回信息,请求过程中不需要跳转页面
    tomcat部署web项目的3中方法
    Date()日期转换和简单计算
  • 原文地址:https://www.cnblogs.com/Bita/p/5511720.html
Copyright © 2011-2022 走看看