Skip to content

Latest commit

 

History

History
328 lines (232 loc) · 7.37 KB

442-203874-[专业选修]位运算符_按位与或非_bitwise_非与或.sy.md

File metadata and controls

328 lines (232 loc) · 7.37 KB
show version enable_checker
step
1.0
true

位运算符

回忆

  • 上次深入了解了str.format
参数 含义 选项
[[fill]align] [填充]对齐] <>=#
[sign] 正负号 +-空
["#"] 前缀
[width] 宽度 数值
[grouping_option] 千位分隔符 ,_
["." precision] [.精度] 数值
[type] 类型 bodxefgn
  • 我们还可以输出 数字的二进制形态
    • 让我们再深入一下
    • 二进制运算
  • 看看还有什么好玩的?🤔

尝试二进制加法

i_op_0 = 65
i_op_1 = 32
i_sum = i_op_0 + i_op_1
print("{:08b}-----{}".format(i_op_0,chr(i_op_0)))
print("{:08b}".format(i_op_1))
print("{:08b}-----{}".format(i_sum,chr(i_sum)))
  • 运行结果

图片描述

  • 大写字母A的 序号
    • 加上 (32)10进制
    • 等于 小写字母a的 序号
  • 这个可以展示补码运算吗?

直接运行

i_op_0 = 1
i_op_1 = -1
i_sum = i_op_0 + i_op_1
print("{:08b}".format(i_op_0))
print("{:08b}".format(i_op_1))
print("{:08b}".format(i_sum))
  • 直接硬上不行的

图片描述

  • 怎么办呢?
  • 不要翻页!自己 想想!
  • 或者搜索一下

得到代码

  • 得到了这么一段 代码
i_num = -1
binary_value = bin(i_num & 0xff)
print("Binary Value: {}".format(binary_value))
binary_value = binary_value[2:]
print("Binary Value: {}".format(binary_value))
  • 其中有个运算符没见过

图片描述

&

找到帮助

help()
OPERATORS
  • 找到运算符的帮助手册

图片描述

观察优先级列表

  • 往后翻

图片描述

  • 确实有 非逻辑布尔类型的
    • 与或非运算
  • 不是 Boolean 运算
    • 而是 Bitwise 运算
  • BitWise 什么意思呢?

BitWise

  • bit 是二进制位
  • wise 是智慧
  • bitwise 是按二进制位进行的运算

图片描述

  • 具体研究一下

& 按位与

  • & 按位与
    • 0 & 0 = 0
    • 0 & 1 = 0
    • 1 & 0= 0
    • 1 & 1= 1
  • 3 & 5
    • 即 00000011 & 00000101 = 00000001
  • 所以 3 & 5 的值为 1

图片描述

  • 每一位都要进行与操作
  • 操作的结果就是最终的结果
  • 注意当 n1、n2 是不同的数字时...

不同的数字

图片描述

  • 注意 n1 = 123 时
    • 对应二进制数 0b1111011
    • 其实可以前面人为补零
    • 但如果我想要自动把零补上呢?

自动补零

  • 这不是 撞枪口上 了么?

图片描述

  • 不过话说回来
  • 为什么会有按位与这种操作呢?
  • 有什么意义呢?

状态字 PSW

  • 一个 cpu 除了运算之外
  • 还有一些状态
  • 比如
    • 是否有进位标记
    • 是否有溢出标记
    • 奇偶性标记
      • 就是一些标志位 Flag

图片描述

  • 数据 放在一个程序状态字(Program Status Word)里面

    • 得到的是 整个状态字
    • 但是 只需要某一位
  • 怎么办呢?

按位与

  • 8-bit的信息
    • 存在1-byte中
  • 想要 得到某个位的信息

图片描述

  • 我们用 0 把不相关的遮住了
    • 就可以利用掩码(mask)
    • 得到关于某1位的具体的值
    • 然后观察到在这个字节中
      • 这一位到底是 0 还是 1
    • 这样就 可以 通过某一位设置好一个开关量
  • 那么 按位或 有什么用呢?

按位或

  • 参加运算的两个数只要两个数中的一个为 1
    • 结果就为 1。
    • 0 | 0 = 0
    • 1 | 0 = 1
    • 0 | 1 = 1
    • 1 | 1 = 1

图片描述

  • 例:2 | 4 即
    • 00000010 | 00000100 = 00000110
    • 所以 2 | 4 的值为 6

按位或举例

图片描述

  • 回忆一下文件锁
    • 独享 按位或上 非阻塞
    • 得到了 非阻塞独享
  • 与和或 有什么区别呢?

与和或

  • 是不同的规则
    • 01 是不同的状态
    • 0 可以在 操作中起到屏蔽的作用
    • 1 可以在 操作中起到屏蔽的作用
  • 也就是俗称的掩码 mask
    • 与和或都有了
    • 非在哪里呢?

按位取反~

  • 按位取反
    • 也称作“按位取非”或“求非”或“取反”
    • 沈洁元译本译作“按位翻转”
    • 是针对二进制数的操作
    • 指将两个二进制数的每一二进位都进行取反操作
      • 0 换成 1
      • 1 换成 0
  • 可以按照给出的公式记忆
    • ~6 = -(x+1)= -7

图片描述

  • 他们加起来是-1
  • 对应二进制形态所有位都是 1
  • 可以具体举例么?

具体例子

  • 取反是对于每一个二进制位来说的

图片描述

  • 对于整个数字来说的话
    • 就是逻辑非 not 而不是按位非 ~

图片描述

按位异或

  • 异或是二元运算符
    • 就是看这两位是不是不同
      • 不同就是 1
      • 相同就是 0
  • 异或的英文是 XOR
    • exclusive or
    • or 的基础上把 and 去掉就是 xor

图片描述

  • 参加运算的两个数

    • 如果两个相应位为“异”
    • 值不同
    • 则该位结果为 1
  • 否则为 0

    • 0 ^ 0 = 0
    • 0 ^ 1 = 1
    • 1 ^ 0 = 1
    • 1 ^ 1 = 0
  • 2 ^ 4

    • 即 00000010 ^ 00000100 = 00000110
    • 所以 2 ^ 4 的值为 6
  • 按位异或有什么实际意义呢?

求反

图片描述

  • 把某个字节与全1异或之后
  • 就得到了这个字节按位取反的数值

图片描述

按位异或

  • 通过按位或可以得到编程状态字的某位
    • 如果结果是1的话,字节全1
    • 如果结果是0的话,该位为0,其余为1

图片描述

  • 这个结果通过和全1按位异或
    • 得到一个和原来结果按位求反的字节状态

位运算符总结

  • 概念都来自数字电路

图片描述

  • 不过在程序里面
    • 也可以通过 位运算符 完成相应的计算
  • 他们 都可以对应到 cpu 的指令

总结

  • 这次了解的是
    • bitwise 运算符
效果 英文 符号 操作数
按位与 bitwise and & 2
按位或 bitwise or | 2
按位非 bitwise not ~ 1
按位异或 bitwise exclusive or ^ 2
  • 这一切都是从str.format引发出来的
  • str.format 可以使用 上下文 中的 变量吗?🤔
  • 下次再说 👋