位运算及诸技巧

2023-11-10

位运算及诸技巧

位运算概念:基于二进制的位的运算
对于位运算,注意两点:
1.必须以二进制角度进行位运算
2.必须以补码角度进行位运算

位运算符:
(1) 按位取反 ~
求~1
具体过程
1的补码为:
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

计算机验证

int n = 1;
printf("%d\n",~n);

输出结果为:-2

(2) 按位与 &
求12 & 5
具体过程
12的补码为:
0000 0000 0000 0000
0000 0000 0000 1100(补)
5的补码为:
0000 0000 0000 0000
0000 0000 0000 0101(补)
12&5:
0000 0000 0000 0000
0000 0000 0000 0100(原、补)
读数:4

计算机验证

printf("%d\n",12&5);

输出结果为:4

(3) 按位或 |
求12|5
具体过程
12的补码为:
0000 0000 0000 0000
0000 0000 0000 1100(补)
5的补码为:
0000 0000 0000 0000
0000 0000 0000 0101(补)
12|5:
0000 0000 0000 0000
0000 0000 0000 1101(原、补)
读数:13

计算机验证

printf("%d\n",12|5);

输出结果为:13

(4) 按位异或 ^
求12^5
具体过程
12的补码为:
0000 0000 0000 0000
0000 0000 0000 1100(补)
5的补码为:
0000 0000 0000 0000
0000 0000 0000 0101(补)
12^5:
0000 0000 0000 0000
0000 0000 0000 1001(原、补)
读数:9

计算机验证

printf("%d\n",12^5);

输出结果为:9

(5) 右移 >>
右移的概念:右移是指二进制数据整体右移,右移n位,最后的n位无论是几都去掉;最高位缺的部分需要补位;对于有符号数:最左侧缺的几位用符号位补齐;对于无符号数:最左侧缺的几位都用0补齐。
右移n位的本质为:除以2^n;
例子:求下列有符号数与无符号数右移两位后的值

char n = 0xAC;
具体过程
(1010 1100)补
n>>2 = (1110 1011)00(补)
( 对于有符号数用符号位补齐)
变为原码:
1001 0101
读数:-21 十六进制补码表示:0xEB
计算机验证

  char n = 0xAC;
  printf("%d\n",n >> 2);

输出结果为:-21

unsigned char n = 0xAC;
具体过程
(1010 1100)补
n >> 2 = (0010 1011)00(补、原)
读数:43

计算机验证

  unsigned char n = 0xAC;
	printf("%d\n",n >> 2);

输出结果为:43

(6) 左移 <<
左移概念:不论左移几位,缺失的位有用0补齐。
左移n位的本质为:乘2^n
例子:输出1左移i位的值(i的范围为0~31)

	int n = 1;
	int i;

	for(i = 0;i < 32;i++) {
	printf("%d:%u %x\n",i,n << i,n << i);
	}

输出结果为:
在这里插入图片描述

位运算诸技巧

1.关于&
假设有一个数,现需要取这个数所对应的二进制的后三位。
如:n = 0100 0101
只想要后三位,&0 = 0;&1 = 本身
则n&7
0100 0101
& 0000 0111
n&7 0000 0101
进一步思考,从二进制角度看n%8也可取出后三位,但算术运算速度远低于逻辑运算速度(可以看成位运算)即用n&7代替n%8是为了加快运算速度。

2.关于异或
(1) 加密解密
加密:
明文 0100 1100
密钥 1000 0111
密文 1100 1011

解密:
若已知密文的加密方式及密钥,则可解密:
密文 1100 1011
密钥 1000 0111
铭文 0100 1100

(2) 局部按位取反
A B A^B
0 0 0
1 0 1
0 1 1
1 1 0
发现 A^0 = 本身
A^1 = !A
即想要取反的那位与1异或即可按位取反。
假设任意数num(假设是1B无符号数),希望对b4b3b2按位取反,其他各位保持不变;特别提醒:1B数的每一位按照如下顺序命名:
b7b6b5b4b3b2b1b0
0 0 0 1 1 1 0 0
结果b7 b6 b5 !b4 !b3 !b2 b1 b0

3.设置某一位为0或1
设置某一位为1称为置位
设置某一位为0称为清位

被设置的位的范围在一个字节之内,即,在b0到b7范围内,为了操作方便,重新对一个字节的8位进行排列。
b0 b1 b2 b3 b4 b5 b6 b7

置位
已知num和i,num表示一个一字节数值,i表示从左向右这个字节的第i位,i取值从0到7,要求将num的第i位置位。

由于A|1 = 1; A|0 = 本身;让所要置位的那一位与1相或即可

xxxx xxxx
|
0000 0001
0000 0010
0000 0100
0000 1000
0001 0000
0010 0000
0100 0000
1000 0000

上述操作分别将num的第7位置位,第6位置位…第0位置位。相当于1 << 0,1<< 1 … 1<< 7.
在这里插入图片描述
观察发现:两列二进制数据后三位按位取反,回忆运算位技巧2中按位异或局部取反,即, 1 << (i^7)
用i把左移的位数表示出来!

总结:num不动,把1移到第i位,与num相或!即,((num) |=(1 << (i ^ 7 )))

清位

由于A&1 = 本身; A&0 = 0;让所要置位的那一位与0相与即可

xxxx xxxx
&
1111 1110
1111 1101
1111 1011
1111 0111
1110 1111
1101 1111
1011 1111
0111 1111

上述操作分别将num的第7位清位,第6位清位…第0位清位。相当于~(1 << 0),~(1<< 1) …~( 1<< 7).

总结:num不动,把0移到第i位,与num相与!即,((num) &=(~(1 << (i ^ 7 ))))

取位

abcd efgh
&
0000 0001
取出最后一位:h

abcd efgn整体右移一位:
aabc defg
&
0000 0001
取出当前最后一位:g

以此类推得到结论: 将所取位移到数值的最右侧,然后和1相与,即可取出abcdefgh的每一位!即,(num >> ((i) ^ 7)) & 1

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

位运算及诸技巧 的相关文章

  • OLED拼接屏连接方法,需要注意哪些事项?

    OLED拼接屏是由多个OLED屏幕拼接而成的大屏幕 可以用于展示大型广告 信息发布 舞台背景等场合 在拼接OLED屏幕时 需要注意接法 以确保整个屏幕的显示效果和稳定性 首先 需要选择合适的OLED屏幕 一般来说 拼接屏幕的每个单元都应该是
  • PHP 23种设计模式

    设计模式的目的 重用性 相同功能的代码 不用多次编写 可读性 编程规范性 便于其他程序员的阅读和理解 可扩展性 当需要增加新的功能时 非常的方便 称为可维护 可靠性 当我们增加新的功能后 对原来的功能没有影响 使程序呈现高内聚 低耦合的特性
  • redis 3.0的集群部署

    文章转载自 http hot66hot iteye com blog 2050676 转载请注明出处 http hot66hot iteye com admin blogs 2050676 最近研究redis cluster 正好搭建了一个

随机推荐

  • 使用ChatGPT的gpt-3.5-turbo模型, PHP接入代码

  • CAN 总线通信 简要概括

    CAN 通信总线协议 简要概括 CAN 介绍 CAN 类型 高速 CAN 低速 CAN CAN 总线系统结构 CAN bus通信帧 CAN 基本数据帧结构 CAN 硬件设计 CAN 介绍 CAN Controller Area Networ
  • 2022年Python面试题汇总【面试官爱问】

    2022年Python面试题汇总 常问 1 请你讲讲python获取输入的方式 以及python如何打开文件 2 Python数据处理的常用函数 3 请你说说python传参传引用 4 请你说说python和java的区别 5 Python
  • IPv6知识概述 - IPv6地址

    IPv6知识概述 IPv6地址 IPv6地址表示 根据RFC4291 IPv6地址有3中格式 首选格式 压缩表示和内嵌IPv4地址的IPv6地址表示 首选格式 IPv6的地址长度是128位 bit 将这128位的地址按每16位划分为一个段
  • wincc怎么做一个弹出画面_Wincc如何利用单个弹出窗口画面的模板,来实现调用多组画面参数?...

    点击上方蓝色字 小叔聊自控 在后台回复关键字 画面脚本 即可获得本次视频中的所有文件及项目包 以下视频中包含本期所有内容 大家好 我是小叔 今天我们来了解一下Wincc如何利用单个弹出窗口的画面模板 来实现调用多组画面参数的方法 怎么来理解
  • Unity版本更新之后IOS审核提示机型适配变少

    之前用2020 3 1提交IOS白包 后来更新版本后使用2020 3 10打包的 提示适配 机器变少了 We identified one or more issues with a recent submission for App St
  • 问题集锦~

    1 Wireshark抓包过程遇到的一点小问题 在使用wireshark进行抓包时 发现目标为本机时 无法抓包 这是由于wireshark并不会抓取本机loop的流量 只会抓取流经网卡的流量 如果需要使用wireshark抓取本机的数据包
  • Q_DECLARE_PRIVATE与Q_DECLARE_PUBLIC

    Q DECLARE PRIVATE与Q DECLARE PUBLIC 这两个宏在Qt的源码中随处可见 重要性不言而喻 在 部落格的 Inside Qt Series 系列文章中 他用了3篇文章来讲这个问题 因为 QObject 本身比较复杂
  • java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener问题

    解决方案 1 spring web的jar包缺失 2 刷新工程 因为工程是部署在服务器下的 可能没被检测到
  • Spring Web MVC框架(六) 异常处理

    Spring Web MVC对异常处理有着完善的支持 我们可以捕获控制器中抛出的任何异常 然后按照异常类型将异常信息映射到某个视图文件 向用户显示对应的信息 ExceptionHandler 最简单的办法就是使用 ExceptionHand
  • PyTorch中nn.Module类中__call__方法介绍

    在PyTorch源码的torch nn modules module py文件中 有一条 call 语句和一条forward语句 如下 call Callable Any call impl forward Callable Any for
  • java 反射lib下的jar_JAVA通过反射调用外部的jar包

    把外包jar的信息写在配置文件中 这样如果外部jar改变了 只需要修改properties相应的配置即可 config properties文件内容如下 jarUrl E MessageSend jar className org line
  • 为Android安装BusyBox —— 完整的bash shell

    http www cnblogs com xiaowenji archive 2011 03 12 1982309 html 大家是否有过这样的经历 在命令行里输入adb shell 然后使用命令操作你的手机或模拟器 但是那些命令都是常见L
  • 星星之火-35:为什么傅里叶分析需要引入负频率以及负频率的物理意义是什么?

    1 傅里叶分析的量化模型 下图是通过傅里叶分析从时域信号中获取谐波分量的幅度特征的基本模型 是不是似曾相识 是的 这个模型就是从高频已调信号中解调出基带信号的模型 该模型是利用函数正交性原理 通过指定频率的复指数信号 从时域信号中获取指定频
  • Python 终端进度条评测 包含一个作者自定义的轻量案例源码

    Python 终端进度条对比评测 效果展示 TPDM 代码部分 输出包体 129M RICH 代码部分 输出包体 68M 当前案例 代码部分 包体大小 总结 你可以根据你的实际情况来做出选择 效果展示 TPDM 可以看到效果是蛮好的 其次
  • MQ线上平滑迁移方案

    一 迁移的问题点 1 多生产者 多消费者切换排期跨度较大 场景一 多个生产者 一个消费者 如何保证多个生产者不同排期切换平滑稳定过渡 不漏消费 不重复消费 场景二 一个生产者 多个消费者 如何保证多个消费者不同排期切换平滑稳定过渡 不漏消费
  • Linux——Docker网络通信

    文档中使用的镜像不同 自行选择镜像 Docker Docker提供了映射容器端口到宿主机和容器互联机制来为容器提供网络服务 一 Dockerhost单主机网络 Docker网络从覆盖范围可分为单个host上的容器和跨多个host的网络 DO
  • C# 操作Kafka

    1 C 连接Kafka知识分享 前些天公司的Boss突然下达一个命令 消息中间件要用Kafka 既然领导都决定了用就用呗 那就网上百度一下去Kafka如何安装啊 Kafka用代码如何连接操作 在安装和使用过过程中遇到了一些坎坷的事情 最总还
  • No package openstack-keystone available.Nothing to do

    root controller yum repos d yum y install openstack keystone httpd mod wsgi python openstackclient memcached python memc
  • 位运算及诸技巧

    位运算及诸技巧 位运算概念 基于二进制的位的运算 对于位运算 注意两点 1 必须以二进制角度进行位运算 2 必须以补码角度进行位运算 位运算符 1 按位取反 求 1 具体过程 1的补码为 0000 0000 0000 0000 0000 0