位运算:利用计算机的二进制计算原理进行运算的 C++ 运算符

位运算 位运算是计算机中进行二进制操作的一种方法。它可以对二进制数的单个比特位进行操作,包括位移、按位与、按位或、按位异或、按位取反等。位运算可以用于很多场景,例如:对于需要对程序中的某一或几位进行操作时,比如需要将一个数的某一位设为1或者设为0,这时就可以使用按位运算。在内存管理中,程序常常需要对内存地址进行位运算,以判断对齐、分页和分段等问题。位运算还可以用于加密和解密算法中,提高运算效率并增加加密强度。位运算可以进行逻辑推理,例如二进制数的“灰码编码”等,常用于工业自动化和数字信号处理领域等。 阅读详情

一、位运算的实质和定义

二进制是计算机的基本操作单位,而位运算就是计算机采用的基本运算方式。在计算机内部,所有数据都按照二进制的方式储存和进行处理,因此位运算在计算机科学中尤为重要。由于位运算是计算机进行处理和运算的基础,所以使用位运算有以下几点好处:

  • 执行效率相比传统的加减乘除四则运算较高。
  • 定义相比传统四则运算在计算机中更加明确且不容易出现歧义。
  • 一些高级的数据结构和算法(比如线段树和树状数组)需要使用位运算提高运行效率和代码简洁程度。

但是,我们还是需要处理一些特殊的问题,比如运算符的优先级问题和运算的基本原理。
综上所述,位运算是计算机的基本运算,具有执行效率高的优点,但也存在优先级容易混淆、容易概念不清的缺点。

二、常见的位运算

下面我将用一张表格来说明位运算的分类和运算方式。

运算符运算方式举例
与(&)把两个数的每个二进制位进行逻辑与运算,只有两个位都为 1 1 1 ,结果才是 1 1 1 。 3   &   5 = ( 11 ) 2   &   ( 101 ) 2 = ( 1 ) 2 = 1 3 \text{ }\&\text{ } 5=(11)_2\text{ }\&\text{ }(101)_2=(1)_2=1 3 & 5=(11)2​ & (101)2​=(1)2​=1
或(|)把两个数的每个二进制位进行逻辑或运算,两个位中只要有一个是 1 1 1 ,结果就是 1 1 1 。 3   ∣   5 = ( 11 ) 2   ∣   ( 101 ) 2 = ( 111 ) 2 = 7 3 \text{ }|\text{ } 5=(11)_2\text{ }|\text{ }(101)_2=(111)_2=7 3 ∣ 5=(11)2​ ∣ (101)2​=(111)2​=7
异或( ^)把两个数的每个二进制位进行异或运算, 两个位不同,结果就是 1 1 1 ,否则就是 0 0 0 ,即 1 xor 0 = 1, 1 xor 1 = 0, 0 xor 0 = 0, 0 xor 1 = 1 。 3  xor  5 = ( 11 ) 2  xor  ( 101 ) 2 = ( 110 ) 2 = 6 3 \text{ xor } 5 = (11)_2 \text{ xor } (101)_2 = (110)_2 = 6 3 xor 5=(11)2​ xor (101)2​=(110)2​=6
左移(<<)把一个数左移指定位数,空白部分填充 0 0 0 。 3 < < 5 = ( 11 ) 2 < < 5 = ( 1100000 ) 2 = 96 3 << 5 = (11)_2 << 5 = (1100000)_2 = 96 3<<5=(11)2​<<5=(1100000)2​=96
右移(>>)把一个数右移制定位数,去掉右移后被挤掉的部分。 5 > > 3 = ( 101 ) 2 > > 3 = 0 5 >> 3 = (101)_2 >> 3 = 0 5>>3=(101)2​>>3=0

从上面的图标,我们可以看出,常见的位运算是与、或、异或三种运算,其中与预算和或运算的运算规则与其逻辑运算符的运算规则相近,但异或运算符的运算规则与传统的逻辑运算符有所不同。以上三种运算由于是计算机直接处理并运算,所以复杂度相对四则运算较低。

除此之外,位运算的优先级也应该注意。下面我将利用一张图表来说明位运算的优先级。

  1. 位运算内部:<< > >> > & > ^ > |
  2. 总体的运算优先级:位运算符 > 逻辑运算符 > 算术运算符

如果我们不确定需要使用哪种运算符,应该加上小括号 () 来指定运算顺序。

我们将会用下面的实例程序来说明位运算在 C++ 中的具体运用:

#include <bits/stdc++.h>

using namespace std;

int main()
{
	int a = 3 & 5;
	cout << a << endl; //1

	a = 3 | 5;
	cout << a << endl; //7

	a = 3 ^ 5
	cout << a << endl; //6

	a = 3 << 5;
	cout << a << endl; //96

	a = 5 >> 3;
	cout << a << endl; //0

	return 0;
}

三、利用位运算进行的简单操作

  1. 常见的用位运算代替传统四则运算的表达式
  • N < < 1 = 2 N N << 1 = 2N N<<1=2N
  • N > > 1 = ⌊ N 2 ⌋ N >> 1 = \lfloor \large{\frac{N}{2}} \rfloor N>>1=⌊2N​⌋
  • k < < N = 2 N k k << N = 2^Nk k<<N=2Nk
  • N > > k = ⌊ N 2 k ⌋ N >> k = \lfloor \large{\frac{N}{2^k}} \rfloor N>>k=⌊2kN​⌋
  1. 查找一个正整数 N N N 的第 k k k 位是否为 1 1 1

  结论:计算 N > > k   &   1 N>>k\text{ }\&\text{ }1 N>>k & 1 或 N   &   ( 1 < < k ) N\text{ }\&\text{ }(1<<k) N & (1<<k) 的值即可。
  证明:
(1)  ∵ \because ∵ N > > k = N 2 k N>>k=\large{\frac{N}{2^k}} N>>k=2kN​ (右移 >> 的运算规则) ,
∴ \therefore ∴ 计算 N > > k   &   1 N >> k \text{ } \& \text{ } 1 N>>k & 1 的值就可以判断 N N N 右移 k k k 位后的最后一位是否是 1 1 1 。
∴ \therefore ∴ 我们可以得到 N N N 的第 k k k 位是否是 1 1 1 。
(1)的代码实例:

#include <bits/stdc++.h>

using namespace std;

int n, k;

int main()
{
	cin >> n >> k; //n的第k位
	
	cout << (n >> k & 1) << endl; 
	
	return 0;
}

(2)  ∵ \because ∵ 1 < < k = 2 k 1<<k=2^{k} 1<<k=2k (左移 << 的运算规则),
∴ \therefore ∴ 1 < < k 1<<k 1<<k 是一个除了第 k k k 位的值是 1 1 1 ,其他位上的值都是 0 0 0 的二进制数。
∴ \therefore ∴ 如果 N N N 的第 k k k 位是 1 1 1 , N & ( 1 < < k ) N \& (1 << k) N&(1<<k) 的值就一定是 1 1 1 ,反之就一定是 0 0 0 。
(2)的代码实例:

#include <bits/stdc++.h>

using namespace std;

int n, k;

int main()
{
	cin >> n >> k;

	cout << (n & (1 << k)) << endl; //此处输出的值应该和上面的相同

	return 0;
}

  应用场景:
  在状态压缩中,需要应用这种方法来取出某一位的值来读取相应的信息。比如一行灯的亮灭情况,记亮为 1 1 1 ,不亮为 0 0 0 ,则一种可能的状态可以表示为: 10001111 10001111 10001111 。这时如果我们想在 O ( 1 ) O(1) O(1) 的时间复杂度内查取到第 k k k 盏灯的亮灭情况,则需要利用上面的办法,解决问题。
  状态压缩在 状态压缩 DP 中的应用较为广泛,在一些高级数据结构中也有用处。

  1. 让 N N N 的第 k k k 位取反
    设变化后的 N N N 为 N ′ N' N′ 。
    当 N > > k   &   1 = 0 N>>k\text{ }\&\text{ }1=0 N>>k & 1=0 时,
    ∵ \because ∵ N ′ = N + 2 k × ( 1 − 0 ) = N + 2 k N'=N+2^k \times (1-0)=N+2^k N′=N+2k×(1−0)=N+2k ,
    ∴ \therefore ∴ N ← N + ( 1 < < k ) N \leftarrow N+(1<<k) N←N+(1<<k) ,即 N += (1 << k) 。
    当 N > > k   &   1 = 1 N>>k\text{ }\&\text{ }1=1 N>>k & 1=1 时,
    ∵ \because ∵ N ′ = N + 2 k × ( 0 − 1 ) = N − 2 k N'=N+2^k \times (0-1)=N-2^k N′=N+2k×(0−1)=N−2k ,
    ∴ \therefore ∴ N ← N − ( 1 < < k ) N \leftarrow N-(1<<k) N←N−(1<<k) ,即 N -= (1 << k) 。
    代码实例:
#include <bits/stdc++.h>

using namespace std;

int n, k;

int main()
{
	cin >> n >> k;
	
	if ((n >> k & 1) == 0)
	{
		n += (1 << k);
	}
	else
	{
		n -= (1 << k);
	}
	
	cout << n << endl;
	// 或者去掉上面的条件判断和输出,改为:
	// cout << ((n >> k & 1) == 0 ? n + (1 << k) : n - (1 << k)) << endl;
	
	return 0;
}

四、利用位运算解决实际 OI 问题

  1. 题面描述
    1
  2. 解题方案
    先考虑第一行的 2 5 = 32 2^5=32 25=32 种状态,每一种状态中由五位 0 0 0 和 1 1 1 组成。如果第 1 1 1 行确定,下一行尝试让上一行所有数都变成 1 1 1 。到达最后一行,判断最后一行是否都是 1 1 1 并且转换次数小于等于 6 6 6 。最后,记录答案并输出最小值。
#include <bits/stdc++.h>

using namespace std;

#define ONLINE_JUDGE 1

const int N = 507;
const int dx[5] = {0, 1, 0, -1, 0}, dy[5] = {0, 0, 1, 0, -1};

int n, a[7][7], b[7][7], ans;

void solve(int x, int y)
{
    for (int i = 0; i < 5; ++i)
    {
        int xx = x + dx[i];
        int yy = y + dy[i];

        a[xx][yy] ^= 1;
    }
}

int main()
{
#if ONLINE_JUDGE
    freopen("light.in", "r", stdin);
    freopen("light.out", "w", stdout);
#endif

    cin >> n;
    
    while (n--)
    {
        for (int i = 1; i <= 5; ++i)
        {
            for (int j = 1; j <= 5; ++j)
            {
                scanf("%1d", &a[i][j]);
            }
        }

        ans = 10;
        memcpy(b, a, sizeof(a));

        for (int i = 0; i < 32; ++i)
        {
            memcpy(a, b, sizeof(b));

            int tot = 0;

            for (int j = 1; j <= 5; ++j)
            {
                if (i & (1 << (j - 1)))
                {
                    solve(1, j);
                    tot++;
                }
            }

            for (int j = 2; j <= 5; ++j)
            {
                for (int k = 1; k <= 5; ++k)
                {
                    if (a[j - 1][k] == 0)
                    {
                        solve(j, k);
                        tot++;
                    }
                }
            }

            if (tot > 6) continue;

            int f = 1;
            for (int j = 1; j <= 5; ++j)
            {
                if (a[5][j] == 0)
                {
                    f = 0;
                    break;
                }
            }

            if (f)
            {
                ans = min(ans, tot);
            }
        }

        ans = ans == 10 ? -1 : ans;

        cout << ans << endl;
    }

    return 0;
}
AI报告撰写实战指南:从提示词工程到全流程优化的底层逻辑与实践突破 传统AI写作常被诟病为“信息拼贴”——模型虽能生成文本,却常出现逻辑断裂、数据矛盾、风格不符等问题。而“全流程优化”则是通过系统化设计,将报告生成拆解为需求解析→数据对齐→提示词设计→初稿生成→迭代优化→格式适配六大环节,每个环节均通过技术手段提升输出质量。提示词工程:本质是通过结构化指令(如角色设定、任务分解、格式约束、示例引导)精准控制模型输出方向,是连接用户需求与模型能力的“翻译器”。全流程优化。 阅读详情

相关推荐

Git下载安装及环境配置,解决安装包下载慢问题(详细版)

Git是我们平时开发都要用到的项目管理工具,虽然有网页版的Git网站,但是在本地安装Git后,可以直接使用命令语句来进行项目的上传与克隆。还是非常方便的。今天就来介绍下Git的下载。1、首先在浏览器中搜索Git,进入到Git的官方下载界面或者直接复制下面这个链接。 2、点击download进入下载界面,选择自己需要平台的文件 3、下载标准版就可以4、但是会发现下载速度很慢,就找个镜像版 5、点击 https://registry.npmmirror.com/binary.html?path=git-for-

mengxiang_的博客 6万+

位运算全面总结,关于位运算看这篇就够了

关于位运算的奇技淫巧,看完这篇你就能灵活使用位运算了。

pursuit的博客 12万+

Jetson AGX ORIN硬件初始化和环境部署

orin预安装了ubuntu20.04,只需开机,像重装系统一样设置用户信息即可,可以参考官网的教程[https://developer.nvidia.com/embedded/learn/get-started-jetson-agx-orin-devkit],官网提供了两种方式:一种是orin + 显示器,orin有提供DP接口,你需要准备一台显示器,最好也是有DP口的,因为我用DP转HDMI的连的,分辨率会受影响。确认安装的路径,一般直接回车安装在默认的 /home/你的名字/anaconda3。

TracyGC的博客 3836

位运算详解

位运算,异或,按位或,按位与

weixin_65743593的博客 803

Unity+ARFoundation 探坑之路

前两天想要上手Unity来AR方面的项目东东 ,探索过程中出现了各种各样的问题,现在将这个过程中遇到的各种各样问题梳理一下,希望后来者能开开心心上手Unity+AR。 注意:这是一篇踩坑博客,具体搭建还请自行百度。 一、ARFoundation or ARCore or ARKit Unity作为一个平台,不直接提供XR(包括VR、AR和MR)的开发包,这时就需要其他公司提供各种各样的SDK工具包...

qq_43575926的博客 7134

RK3568 NFS rootfs配置与调试实战指南(已验证)

本文提供了在RK3568开发板上配置NFS rootfs的完整实战指南。通过详细步骤讲解如何配置uboot的bootargs参数、编译支持NFS的内核,并在PC端搭建TFTP与NFS服务器,最终实现从网络挂载根文件系统,从而极大提升驱动调试和应用程序开发的迭代效率。

weixin_29175469的博客 282

(三)位运算

位运算算法

依稀_yixy的博客 1万+

精益六西格玛Python数字化应用开发-Day18 应用场景:家电企业生产效率优化

本文将重点介绍专门针对精益六西格玛黑带使用场景的 Python 库,这些库功能侧重于数据分析和流程优化,特别适用于 DMAIC 方法论和看板管理。考虑到读者具备中高级Python 使用经验,我们将深入探讨各库的高级功能和实际应用应用场景。 某家电企业生产线自动化程度高,数据量巨大,希望通过精益管理提升生产效率。企业借助 Python 脚本,打通各类数据源(MES、ERP、设备日志),自动归集生产数据,分析各工序的生产节拍、设备停机、效率损失,快速定位瓶颈环节

m0_56592100的博客 906

计算机基础知识---位运算的简介

Author:baiyucraft BLog: https://blog.youkuaiyun.com/hjj19991111 1.什么是位运算   稍微有点计算机基础的都知道一点,在程序中的所有数在计算机内存中都是以二进制的形式存储的。位运算就是直接对整数在内存中的二进制进行操作。明白了这个,让我们来看看在Python中有哪些位运算符。 2.位运算符 符号 名称 描述 & 按位与 两个数相应位都为1,则该位的结果为1,否则为0 | 按位或 两个数相应位有一个为1,则该位的结果为1,否则为

baiyucraft的博客 1199

LangChain面试内容整理-知识点27:LangChain性能调优

LLM应用可能面临响应慢、成本高等性能问题。LangChain提供了一些优化方法和经验来提升性能和效率。

不务正业的猿 327

YOLOv11 改进 - SPPF模块 | 发论文神器!LSKA注意力改进SPPF,增强多尺度特征提取能力,高效涨点!!!

本文介绍了Large Separable Kernel Attention (LSKA)模块及其在YOLOv11中的结合应用。LSKA旨在解决Visual Attention Networks (VAN)使用大内核卷积时的计算效率问题,通过将2D深度卷积层的卷积核分解为级联的水平和垂直1-D卷积核,降低了计算复杂度和内存占用,且使VAN更关注物体形状。我们将集成LSKA的SPPF_LSKA模块引入YOLOv11,大量实验表明,改进后的模型在对象识别、检测、分割和稳健性测试上表现出色。

魔改工程师的博客 1279

位 与 或 异的概念和计算(借鉴)

什么是位计算 ? 位计算首先是以 一个数的二进制形式进行计算,判断然后返回每一位得出的结果 一、与(&)计算符 位与:两个操作数 同位上的数 都为 1 才为1 其他情况都为0 例如:整数 a = 15   整数 b = 127 计算:(a & b) 15的二进制位:...

惊鸿的博客 1284

【异常】Milvus向量数据库的常见错误“collection not loaded“(集合未加载)

Milvus数据库报错"collection not loaded"分析及解决方案。该错误发生在对未加载的集合执行查询操作时,核心原因是集合创建后需先加载到内存才能使用。解决方案包括:1)确认集合是否存在;2)查询前调用loadCollection接口加载集合;3)处理加载超时或失败情况,可检查加载状态;4)确保Milvus服务正常运行。建议在长期不使用集合时释放内存资源。文末附Java代码示例说明具体操作方法。

奶爸的编程之路,也就一周冷个三天 380

C++ STL bitset 位图

bitset// 1. 默认初始化:所有位都置为0// 8位位图,初始值:00000000// 2. 整数初始化:用无符号整数的二进制表示初始化,超出位数部分截断// 7的二进制是00000111,bs2的值:00000111// 十六进制0x0A=10,二进制00001010,bs3的值:00001010// 3. 字符串初始化:用二进制字符串(仅含'0'和'1')初始化,不足位数补0// 字符串长度4,高位补0,结果:00001010// 字符串长度6,正好匹配位数,结果:010101。

堇荼如饴风禾尽起~ 633

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

c语言课程设计作业代码,C语言课程设计(简易计算器设计)带所有代码.doc

C语言课程设计(简易计算器设计)带所有代码.doc《C语言课程设计》报告设 计 题 目: 简单计算器设计学 院 名 称: 电子与信息工程学院专 业: 计算机科学与技术班 级: 计科姓 名: 学 号指 导 教 师:定稿日期: 2013-5-28设计题目简...

weixin_31512775的博客 933

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

树状数组 介绍 及应用 C++代码实现+模板+例题

1.问题来源 动态连续和查询问题。给定一个 n个元素的数组 A1,A2,...,An,你的任务是 设计一个数据结构,支持以下两种操作。 ★ Add(x,d)操作:让 Ax增加 d. ★ Query(L,R):计算 AL+AL+1+...+AR. 对普通数组进行一次修改或特定区间求和,时间复杂度为 O(N),N为修改 或求和需要扫描的数组区间大小。但有一种称为树状数组(又称二叉索引...

小渣渣的博客 655

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C++—位运算

C++位运算简介、示例和应用,位匀速主要包括与、或、异或、非、左移和右移;在位运算非的介绍中描述了负数的存储方式和补码的概念。

shouhu010的博客 4205

位运算各种方法总结

位运算1、按位与2、按位或3、按位取反4、按位异或5、按位同或6、左移7、带符号右移8、无符号右移9、python实现各种位运算操作 \quad \quad现代计算机中,几乎都是二进制计算机(三进制计算机仅有少量),所有的数据都以二进制的形式存储在设备中。位运算就是直接对整数在内存中的二进制位进行操作。 \quad \quad需要注意,位运算是针对 二进制 的运算,对每一个位进行布尔运算操作。所以 手动 进行 位运算计算 时,需要将数转换成二进制的表示形式,再进行计算。 1、按位与 \quad \quad只

weixin_45666566的博客 7976

位运算总结(超全解释及代码演示)

位运算总结(超全解释及代码演示)

m0_64231944的博客 1316

位运算原理及使用讲解(带图、超详细)

前言 日常开发中位运算不是很常用,但是巧妙的使用位运算可以大量减少运行开销,优化算法。 举个例子,翻转操作比较常见,比如初始值为1,操作一次变为0,再操作一次变为1。可能的做法是使用三木运算符,判断原始值为1还是0,如果是1,设置为0,否则设置为0.但是使用位运算,不用判断原始值,直接改变值就可以:   1^num//num为原始值 当然,一条语句可能对代码没什么影响,但是在高重复,大数据量的情况下将会节省很多开销。 以下是自己整理的关于java位运算的部分内容,如有错误,还请指出,以共同进步

eden_Liang的博客 5108

位运算总结

现代计算机中,几乎都是二进制计算机,所有的数据都以二进制的形式存储在设备中。位运算就是直接对存储在内存中的数据的二进制位进行操作。在计算机中,每一个二进制位称为1个bit,单位简写做 b。通常8个bit为一个单位,称为字节(byte),单位简写作 B。位运算执行效率非常高,在程序中尽量使用位运算进行操作,这样会大大提高程序的性能。

Kk的博客 795

位运算(按位与、按位或、异或、取反)以及原码、反码、补码

由于[1111_1111]+[0000_0001]=[0000_0000],所以在负数反码的基础上+1就可以解决反码中跨0的误差问题,同时不会对负数与它对应的二进制反码的同步递增产生影响,所以在反码的基础上+1就完美的解决了符号参与预算的问题,这就是补码为什么是在负数反码的基础上+1的由来。用第一位表示符号,其余位表示值。从上面的原码表中可以看见左边每增加一个二进制单位对应的真数是递减的,而右边每增加一个二进制单位对应的真数是递增的,所以对于原码来说,能满足正数的加法,但无法满足负数的加法。

番茄的博客 1万+

C语言中的位运算

在计算机程序中,数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作。一般的位操作是用来控制硬件的,或者做数据变换使用,但是,灵活的位操作可以有效地提高程序运行的效率。C语言提供了位运算的功能, 这使得C语言也能像汇编语言一样用来编写系统程序。 C语言中的位运算

TruthS的专栏 2806

算法数据结构——位运算(Bit Operation)使用方法总结

位运算(Bit Operation):在计算机内部,数是以「二进制(Binary)」的形式来进行存储。位运算就是直接对数的二进制进行计算操作,在程序中使用位运算进行操作,会大大提高程序的性能。在学习二进制数的位运算之前,我们先来了解一下什么叫做「二进制数」。二进制数(Binary):由 $0$ 和 $1$ 两个数码来表示的数。二进制数中每一个 $0$ 或每一个 $1$ 都称为一个「位(Bit)」。我们通常使用的十进制数有 $0 \sim 9$ 共 $10$ 个数字,进位规则是「满十进一」。例如:$7。

白话机器学习 2306
上一篇: 贪心算法的应用实例:子问题的局部最优解可推导出全局最优解
下一篇: 多源最短路的两种做法和详细解析
Aobing_peterJr
博客等级 码龄2年 128粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值