首页 > 其他分享 >位运算例子

位运算例子

时间:2024-11-14 11:07:35浏览次数:1  
标签:num 运算 bytes 例子 bit 清零 data uint32

嵌入式C语言位操作的一些常见用法归纳

一、常用的方法

借鉴 野火STM32 开发板教程中的内容

1. 变量的某位清零

//定义一个变量 a = 1001 1111 b(二进制数)
unsigned char a = 0x9f;
//对bit 2 清零
a &= ~(1<<2);
//括号中的1左移两位,(1<<2)得二进制数:0000 0100 b
//按位取反,~(1<<2)得 1111 1011 b
//假如a中原来的值为二进制数:a = 1001 1111 b
//所得的数与a作"& 位与"运算,a = (1001 1111 b) & (1111 1011 b),
//经过运算后,a的值a = 1001 1011 b
//a的bit2位被清零,而其它位不变。

2. 变量的某几个连续位清零

//若把a中的二进制位分成2个一组
//即bito、bit1为第0组,
//bit2、bit3为第1组,
//bit4、bit5为第2组,
//bit6、bit7为第3组
//要对第1组的bit2、bit3清零
a &= ~(3<<2*1);
//括号中的 3 左移两位,(3<<2*1)得二进制数:0000 1100 b
//按位取反,~(3<<2*1)得 1111 0011 b
//假如 a 中原来的值为二进制数:a = 1001 1111 b
//所得的数与a作"& 位与"运算,a = (1001 1111 b) & (1111 0011 b),
//经过运算后,a的值a = 1001 0011 b
//a的第1组的bit2、bit3被清零,而其它位不变。
//上述(~(3<<2*1)中的(1)即为组编号;如清零第3组bit6、bit7此处应为3
//括号中的(2)为每组的位数,每组有2个二进制位;若分成4个一组,此处即为4
//括号中的(3)是组内所有位都为1时的值;若分成4个一组,此处即为二进制数"1111 b"
//例如对第2组bit4、bit5清零
a &= ~(3<<2*2);

3. 对变量的某几位进行赋值

//a = 1000 0011 b
//此时对清零后的第2组bit4、bit5设置成二进制数“01 b”
a |= (1<<2*2);
//a=1001 0011 b,成功设置了第2组的值,其它组不变

4.对变量的某位取反

//a = 1001 0011 b
//把bit6取反,其它位不变
a^=(1<<6);
//a=1101 0011 b

二、应用例子

1. 二进制置各种状态值

比如以一个16位的二进制表示各种状态值。例如第一位代码置1代表小车急停按下,置0代表解除小车急停。

enum StatusTypes{
        AGV_STOP_BUTTON_PRESSED=0,//小车急停按下
        AGV_UNKNOWN_ERROR=1,//小车未知错误
        CHARGE_CONNECTED_ERROR=2,//充电连接错误
    };

void MainWindow::setStatusCode(bool isSet1,StatusTypes statusTypes)
{
    if(isSet1)
    {
        statusCode_=statusCode_|(1<<statusTypes);

    }
    else
    {

        statusCode_=statusCode_&(~(1<<statusTypes));
    }
    qDebug()<<QString("%1").arg(statusCode_,16,2,QLatin1Char('0'));
}

void MainWindow::on_pushButton_clicked()
{
   setStatusCode(true,AGV_STOP_BUTTON_PRESSED);
   setStatusCode(true,CHARGE_CONNECTED_ERROR);
   setStatusCode(false,CHARGE_CONNECTED_ERROR);
}

"0000000000000001"

"0000000000000101"

"0000000000000001"

2. 查看第几位状态值,参数bit第几位推荐使用enum类型,便于维护。

//num 数值  bit 第几位的值  从右边开始数第一位为0,第二位1
int MainWindow::getStatusValue(int num,int bit)
{
    return (num >> (bit)) & 1;
}
void MainWindow::on_pushButton_clicked()
{

  int16_t num=5;
  int status=getStatusValue(num,2);
  if(status==1)
  {
      
  }
  
}

3. 置位

#define setbit(x,y) x|=(1<<y) //将X的第Y位置1  
#define clrbit(x,y) x&=~(1<<y) //将X的第Y位置0

4. 32位和8位数转换

#include <iostream>
#include <cstdint>

// 分割32位整数为4个8位部分
void splitInt32ToBytes(uint32_t value, uint8_t bytes[4]) {
    bytes[0] = (value >> 24) & 0xFF;  // 高字节
    bytes[1] = (value >> 16) & 0xFF;
    bytes[2] = (value >> 8) & 0xFF;
    bytes[3] = value & 0xFF;          // 低字节
}

// 从4个8位部分合并为32位整数
uint32_t combineBytesToInt32(const uint8_t bytes[4]) {
    return (bytes[0] << 24) |
           (bytes[1] << 16) |
           (bytes[2] << 8)  |
           bytes[3];
}
//4个8位数转换成32位
uint8_t data[4];
data[0]=0x4E;
data[1]=0x11;
data[2]=0x01;
data[3]=0x40;

uint32_t data32;
//注意此处仅等号,如果写成 "|=" 有时转换成的数会不正确的。如数0x4E 0x11 0x01 0x40在keil上转化成功就不对
data32 =  data[0]<<24;

data32 |= data[1]<<16;	
data32 |= data[2]<<8;	
data32 |= data[3];

5. 两个32位数合成带符号的64位数

uint32_t data1 = 0x12345678;
uint32_t data2 = 0x12345678;

int64_t t1 = (int64_t)(((uint64_t)data1<<32)|data2);
double  d1 = t1/10000.0;

qDebug()<<"t1:"<<t1;//t1: 1311768465173141112
qDebug()<<"d1:"<<d1;//d1: 1.31177e+14

//FEDBA987 EDCBA988
uint32_t n1 = 0xFEDBA987;
uint32_t n2 = 0xEDCBA988;

int64_t t21 = (int64_t)(((uint64_t)n1<<32)|n2);
double  d21 = t21/10000.0;
qDebug()<<"t21:"<<t21;//-82285766900995704
qDebug()<<"d21:"<<d21;//d21: -8.22858e+12

标签:num,运算,bytes,例子,bit,清零,data,uint32
From: https://www.cnblogs.com/ike_li/p/18545593

相关文章

  • 初识算法 · 位运算(2)
    目录前言:判定字符是否唯一丢失的数字比特位计数只出现一次的数字III前言:​本文的主题是位运算,通过四道题目讲解,一道是判断字符是否唯一,一道是只出现一次的数字III,一道是比特位计数,一道是丢失的数字。链接分别为:338.比特位计数-力扣(LeetCode) 面试题01.01.判定字......
  • 数据类型和运算符
    数据类型动态类型编程语言运行时判断静态类型的编程语言:Go、C、在开发的时候,就需要给一些定义的变量赋值空间大小。C需要自己去开辟这个空间数据类型:每种在Go语言中出现的基本数据类型,会有一个默认的空间大小。1、布尔类型数据布尔型的值只可以是常量true或者......
  • ECMAScript 安全赋值运算符 (?=) 提案介绍及其 Polyfill
    本文介绍最新的ECMAScript安全赋值运算符提案以及相应的替代实现前言我们经常会跟try/catch打交道,但如果你写过Go或者Rust就会发现在这两种语言中是没有try/catch的,那么这些语言怎么进行错误捕获呢Go:Errorhandlingf,err:=os.Open("filename.ext")iferr......
  • pymilvus连接milvus例子
     #!/usr/bin/envpython#-*-coding:UTF-8-*-frompymilvusimportMilvusClient#创建MilvusClient。client=MilvusClient(uri="http://192.168.1.135:19530",#Milvus实例的公网地址。token="root:Milvus",#登录Milvus实例的用户名和密码。d......
  • PHP运算符
    PHP运算符在PHP中,运算符是一种用于执行各种数学、逻辑和字符串操作的特殊符号。它们允许我们对变量、常量或表达式进行计算和比较。以下是对PHP中各类运算符的详细介绍:1.算术运算符算术运算符用于执行基本的数学运算。加法(+):将两个数相加。减法(-):从第一个数中减去第二个数。......
  • 【c++】运算详解
    运算算术运算符运算符功能+ (单目)正- (单目)负* (双目)乘法/除法%取模+ (双目)加法- (双目)减法单目与双目运算符单目运算符(又称一元运算符)指被操作对象只有一个的运算符,而双目运算符(又称二元运算符)的被操作对象有两个。例如 1+2 中加号就是双目运算符,它有 1 和 2 两......
  • 【C++学习笔记一】变量与运算符
    目录一、C++输出数据1.1数据的分类1.2输出数据二、注释2.1 单行注释2.2 多行注释2.3VS中的快捷键三、变量3.1声明变量3.2变量的赋值3.3示例四、常量4.1宏常量4.2const修饰的变量4.3示例五、标识符的命名5.1C++命名规则5.2C++关键字六、数据输......
  • C 语言运算符
    目录1.算术运算符2.自增运算符,自减运算符3.关系运算符4.逻辑运算符 5.位运算符6.逗号运算符7.运算优先级1.算术运算符算术运算符专门用于算术运算,主要有下面几种。+:正值运算符(一元运算符)-:负值运算符(一元运算符)+:加法运算符(二元运算符)-:减法运算符(二元运算符)*:乘法运算......
  • C中的位运算
    数学基础C中的位运算在C语言中,位运算有以下运算符与(&)或(|)异或(^)取反(~)左移和右移(<<>>)与运算(&)两位都为1时,结果才为10&0=01&0=00&1=01&1=1或运算(|)两位中只要有一位为1,结果为10|0=01|0=10|1=11|1=1异或运算......
  • JavaCC 实战三:整数加法运算
    前两篇文章我们主要介绍了JavaCC安装以及入门介绍。在这篇文章中介绍如何使用Javacc实现判断输入是否是一个合法的加法运算。在如下这个例子中,我们需要实现对如下数字进行加和:99+42+0+15并且在输入中可以允许在数字之间的任意位置出现空格或者换行符。除此之......