首页 > 其他分享 >位运算的基本规则

位运算的基本规则

时间:2023-11-27 16:11:06浏览次数:30  
标签:基本 右移 运算 符号 二进制位 32 规则 类型

在串行通信的过程中,常涉及数据帧的解码与位运算,这里将集中讲解位运算的理解————位运算是计算机科学中的一种基本运算,它主要是对二进制位进行操作。

参考链接:https://blog.csdn.net/qq_39151563/article/details/108305105,内容大部分都是这篇文章中的,下面给出一些记录与理解。

1、常见的位运算  

    我们在计算时,一般使用的是 32位的int 类型(在个人计算机中,int一般为32位)。

      在 n  位二进制数中,我们一般称最低位为第0位,最高位为n − 1位,总右到左依次是第0 , 1 , 2 , ⋯   , n − 1 位,如下图所示

   

         

 

 

 

 

 

 

 

 

在使用的过程中,涉及位运算的运算符如下表所示:

符号 描述 运算规则 举例
& 将参与运算的两个二进制数进行与运算(&),如果两个二进制位都是1,则与运算的结果为1,其他全都为0。(0与任意数N&运算都是0) a&b
| 将参与运算的两个二进制数进行或运算(|),两个二进制位只要其中1个是1 ,那么就是1,如果2个二进制位都是0则表示0。(0与任意数N|运算都是任意数N) a|b 
^ 异或 将参与运算的两个二进制数进行^异或运算,如果2个二进制位都是0或者都是1,那么就是0,如果两个二进制位不同,则为1。 a^b
~ 取反 一元操作符,按位取反。每个二进制位上都取相反值,1变成0,0变成1。 ~a
<< 左移 将一个数各二进制位全部向左移动若干位,左移运算没有有符号和无符号左移动,在左移时,移除高位的同时在低位补0 a<<2 
>> 右移 又称为有符号右移。将一个数各二进制位全部向右移动若干位,若参与运算的数字为正数,则在高位补0;若为负数,则在高位补1。 a>>2 

1.1、左移

左移是将所有二进制位向左移动 n 位(对于32位值n范围是[0,31])。移动后,最左边的 n 个二进制位将因被移出边界而丢弃,移动后最右边空出来的二进制位补0。

对于32位的int型值,如果移动位数超出 32 位,将会被对32取模,如移动 35 位,将变成移动 3 位( 35 % 32 = 3)。所以左移32位并不会变为0,而是相当于移动 0 位,值不变。

 

 

技巧:左移1位相当于在该数乘以2,左移2位相当于该数乘以2*2

在没有发生 溢出 和 环绕 的情况下,n左移一位后的值相当于 2n。

溢出:指的是计算结果超出有符号数存储的范围。
环绕:指的是计算结果超出无符号数存储的范围。

1.2、有符号右移

有符号整数左边的最高位为符号位,代表着数的正负,负数最高位为1,正数和0的最高位为0

有符号数右移时,最右边的位丢弃,最左边的空位补上原来的最高位。有符号右移又叫 算术右移,在算术上相当于是值除以2的结果。

 

   对于有符号数来说,算术右移的结果等于原数除以2再向下取整(公式中,|x|为对x向下取整):

                                                        n >> 2 = |a/2|

      如负数 -3 >> 1  = -2,正数 3 >> 1 = 1。

1.3、无符号右移

无符号数没有符号位,所有位都作为二进制的数值位。右移时,最右边的位丢弃,最左边的位补0。无符号右移又叫逻辑右移。

                                      

2、整数类型之间的转换

 C/C++ 中的整数类型有 charshortintlong 和 long long,这里按类型的位数进行区分,类型的位数越高,那么取值范围就越大,类型就越高级。

一个变量的类型无论是有符号还是无符号,其 存储的二进制内容都是不变的,不同的对这些二进制位的解释方法。

无符号数把最高位作为一个普通的位,而有符号数把最高位作为符号位,相当于改变了最高位的权重,n位无符号数最高位权重是2n-1,而有符号数最高权重是 -2n-1

 如一个八位的无符号数 a,二进制表示为1000 0001,最高位权重是128,最低位权重是1,因此值为 129。当把 a 转成有符号数时,二进制表示依然为 1000 0001,
但此时最高位的含义已经发生了变化,相当于权重 − 128,此时值为 − 127。

 2.1、低级类型向高级类型转换

在整数类型之间的转换中,如果一个变量由 低级类型向 高级类型转换,那么转换时低位不变、高位根据变量 原先的类型 是无符号还是有符号使用不同的方式进行填补

变量原先的类型 高位填补方式
无符号类型 用0填补
有符号类型 用符号位进行填补

 2.2、高级类型向低级类型转换

在整数类型之间的转换中,如果一个变量由 高级类型 向低级类型转换,那么二进制位将会被 截断 ,高位丢弃,只保留低位作为转换后的二进制内容。

最后的值是多少则根据转换后是有符号类型还是无符号类型对二进制位进行解析。

如下图所示,一个16位类型的值转成8位类型,直接截取低8位作为转换后的二进制内容 1010   1101,如果这个8位类型是无符号,那么数值为 173,如果是有符号类型,则是 -83。

 3、常用的位运算操作

 一个字节共8位,最低位是第0 位,最高位是第7 位。如果是32位的 int 型,则最低位为第0 位,最高位为第31位。

                           

 

 1 //取低8位
 2 a & 0xFF
 3 
 4 //取第8至第15位
 5 a & 0xFF00
 6 
 7 //取高16位
 8 a & 0xFFFF0000
 9 
10 //取偶数位
11 a & 0x55555555

掩码:一串二进制代码对目标字段进行位与运算,屏蔽当前的输入位。

          

 示例:
  取32位数中第三个字节的值。第三个字节从第24位开始的8位,所以可以将原数右移24位,然后和低8位掩码0xFF 做 按位与运算 即可得到对应的值。

 1 (a >> 24) & 0xFF;    // 一个字节8个位

标签:基本,右移,运算,符号,二进制位,32,规则,类型
From: https://www.cnblogs.com/Zhouce/p/17859435.html

相关文章

  • 先筛选再提取 两次re.search 通过海象运算符 一次即可
    先筛选再提取两次re.search通过海象运算符一次即可海象运算符,也被称为赋值表达式,是Python3.8版本中引入的一个新特性。它的符号是:=。这个运算符允许你在表达式中进行赋值。这意味着你可以在if语句、while语句或者列表推导等地方,一边计算表达式,一边把结果赋值给变量。下面是一个......
  • 基本数据类型
    数据类型数字类型整数类型(int)浮点类型(float)字符串类型(str)列表类型(list)字典类型(dict)布尔类型(bool)元祖类型(tuple)集合类型(set)【一】数字类型(int/float)【1】整数类型(int)(1)作用整数类型用于表示整数,是一种基本的数字类型,广泛用于表示计数、......
  • Linux系统 基本权限UGO读书笔记
    1.高级权限 高级权限:suidsgidstickysuid:普通用户登陆对于有些文件没有查看权限或者某些命令没有执行命令,例如普通用户不能查看root用户家目录下内容,也不能用passwd对其他文件进行修改,使用suid可以针对单个命令对于普通用户提权限。suid命令格式:chmodu+s命令作用:单独提高一......
  • 位运算
    作用于整数类型的运算对象,对二进制数位进行运算。位与:&当且仅当两个运算对象都为1时,该位为11&1=11&0=00&1=00&0=0eg:255&128=128位或:|当且仅当两个运算对象都为0时,该位为01|1=11|0=10|1=10|0=0eg:255|128=255位取反:~......
  • JVS-rules规则引擎导出与导入,确保业务连续性的关键
    在复杂的系统环境中,规则和配置的迁移、备份及共享成为了确保业务连续性和一致性的关键过程。不同的环境可能需要相同的规则和配置数据,或者我们可能需要备份这些数据以防万一。JVS规则引擎提供了规则的导出与导入功能,使用户能够在多个环境间轻松转移配置数据。每一条配置数据都有其......
  • java基础学习:赋值运算符
    扩展的赋值运算符隐含了强制类型转换  packagecom.itheima.operator;publicclassQperator3{publicstaticvoidmain(String[]args){//目标:掌握扩展赋值运算符的使用//+=//需求类似于收红包doublea=9.5;dou......
  • verilog之“缩减运算符”
    reg[3:0] B;reg    C;assign C=&B;相当于:C=((B[0]&B[1])&B[2])&B[3];注:其他位运算符(~,|,^,&,^~)都有类似用法;   参考链接:verilog之“缩减运算符”-面包板社区(eet-china.com)  if(&b) sys_reset<=1'b0; else sys_reset<=......
  • 透析Java本质的36个话题02运算符与表达式
    1.莫衷一是——i+++j该如何计算?三个加号​ 在java中默认前面结合也就是(i++)+jinti=25;intj=2;intresult=i+++j;System.out.println(i);System.out.println(j);/*262*/贪心规则编译器的贪心规则,分析符号......
  • Java learning Day2 常量 变量 运算符 Scanner 方法 数组
    常量:字面值常量(直接写值的常量)+自定义常量变量:long型变量后必须加L;小数字面值常量默认double 若用float需加F;变量强转:小的会自动转成大的float虽然只有4个字节但是比所有整型的取值范围都大    浮点型有精度问题  表达式类型提升:如果表达式当中存在多种数......
  • 队列(最基本队列,标准队列 2个,双端队列,单调队列)
    2023-11-26最基本队列:一次性使用的classQueue01{//最基本队列,一次性的,数组模拟,先进先出//功能:入队,出队,判满,判空,显示队头,显示队列privateint[]queue;privateintfront=-1;//指向第一个元素前一个位置privateinttail=-1;//指向最后一个元素p......