当前位置: 首页 > news >正文

【位运算进阶之----左移(<<)】

今天我们来谈谈左移这件事。

❤️简单来说,对一个数左移就是在其的二进制表达末尾添0。左移一位添一个0,结果就是乘以2;左移两位添两个0,结果就乘以2 ^ 2左移n位添n个0,结果就是乘以2 ^ n,小心溢出😄!

下面就让我们来详细看看吧!
在这里插入图片描述


文章目录

  • 一、基础知识:
    • :one: 左移的二进制表示:
    • :two: 左移的执行结果:
    • :three: 对负数左移:
    • :four: 左移负数位:
    • :five:左移时溢出!
      • (1)位溢出(移位/mod的角度):
      • (2) 值溢出(值的角度):
  • 二、拓展应用:
    • 1. 取模和位运算的转换:
    • 2. 生成标记码:
      • (1. 标记位置1:
      • (2. 标记位置0:
      • (3. 标记位取反:
    • 3. 生成掩码:


一、基础知识:

✨左移操作是一种位操作,用来将一个数的二进制表达的所有位向左移动指定的位数,并在右侧用0填充空位。

1️⃣ 左移的二进制表示:

✨x<<y 表示将x向左移动y位。(其中x和y都是整数
如:1001 << 2 ----> 100100


2️⃣ 左移的执行结果:

✨左移操作相当于将一个数乘以2的n次方。
x<<y <=> x * (2 ^ y)
如:

#include<stdio.h>int main(void)
{int x = 3, y = 2;printf("%d", x << y);//3*(2^2)return 0;
}

执行结果如下:
在这里插入图片描述
如上图可见,3<<2 = 3 * (2^2)= 3*4 = 12;

  • 可能聪明的你已经想到了左移的强大之处,即对1左移时,得到的都是2的幂,这是一个非常重要的知识点❗️
1左移n位2的幂
1<<122^1
1<<242^2
1<<382^3
1<<n2^n2^n
  • 上面我们讨论的左移都是对正整数来说的,那如果对负数呢?对负数左移会发生什么?左移负数位又是如何?阁下莫急,且听我慢慢道来……

3️⃣ 对负数左移:

如:-3<<2 是多少呢?相信你心中已经有答案了,请看下图!

#include<stdio.h>int main(void)
{int x = -3, y = 2;printf("%d", x << y);return 0;
}

执行结果如下:
在这里插入图片描述
✨(-x)<<y <=>-(x<<y) :即对负数左移y位等于对正数左移y位后再取负。

这其实也可以用补码来解释:

  • -(3<<2):
    • 3的补码:00000000 00000000 00000000 00000011
    • 3的补码左移两位:00000000 00000000 00000000 00001100=12 ,再取负得12。
  • -3<<2:
    • -3的补码:11111111 11111111 11111111 11111101
    • -3的补码左移两位:11111111 11111111 11111111 11110100
    • 转换成原码:10000000 00000000 00000000 00001011+1 = 10000000 00000000 00000000 00001100 = -12。

4️⃣ 左移负数位:

那么,3<<(-2)又是多少呢?😢 放过我吧!💢💢💢

#include<stdio.h>int main(void)
{printf("%d", 32<< (-1));return 0;
}
  • 可能有朋友就要类比了,加上-1就是减去1,那么左移-1位是不是右移一位呢?让我们继续往下看:

在这里插入图片描述

  • 咦,怎么有条波浪线?这是什么?输出怎么会是0?按道理来说r如果是右移那么结果是31/2=16啊!!!

在这里插入图片描述
为什么会有警告?难道我想错了?在这里插入图片描述

  • 让我们寻着警告去看看到底问题出在哪儿了!

警告1 (点我👈)
在这里插入图片描述

警告2(点我👈)
在这里插入图片描述
😄看来左移负数位是未定义的行为啊,所以我们最好不要这样写,可能会带来不必要的麻烦,如果想要右移的话就乖乖使用右移操作。


5️⃣左移时溢出!

✨(非溢出)移位可以分为逻辑移位和算术移位。

  • 无符号整数:逻辑移位,左、右添0;
  • 有符号整数:算术移位,符号位不变,分正负;

✨溢出可以分为位溢出和值溢出(此为博主自己分的,可能不合理,但博主自己觉得合理),而我们又知道,整数分为无符号整数和有符号整数。所以通过组合我们大概了解到,此处的溢出一共有4种情况。

(1)位溢出(移位/mod的角度):

✨对于位溢出来说,我们在上面已经讨论过了,int 类型一共32位,移位大于等于32位或小于0位即为位溢出。

注:在不同的编程语言中,对于超出操作数位数的移位操作,可能会有不同的行为。一些语言会将超出的位数进行取模操作即将移位的位数先对操作数的位数取模,然后再进行相应的位移,比如C语言❗️❗️❗️

(2) 值溢出(值的角度):

✨当变量的值超过了其所能表达的值的范围时,产生值溢出。但溢出的值并不会消失,而是以另一种形式存在着。

下面我们举例来说明:

❤️有符号整数:

#include<stdio.h>int main(void)
{int a = 9;printf("%d\n", a << 31);printf("%d\n", a << 32);//等价于a<<0;printf("%d", a<<33);//等价于a<<1;return 0;
}

执行结果如下:
在这里插入图片描述
如上面的代码所示,a原本是9,其二进制表达为:00000000 00000000 00000000 00001001,现在对其进行左移操作

1️⃣左移31位:(31<32)未溢出

  • 1.从移位的角度来看
    • 第一步,左移31位:10000000 00000000 00000000 00000000(负)
    • 第二步,再求出其原码:01111111 11111111 11111111 1111111+1=10000000 00000000 00000000 00000000(先记下符号位,然后各位取反,末位加一,再回归符号位)
    • 第三步,可以看出这是最小的数:也即-2^31=-2147483648
  • 2.从值的角度来看:
    因为9<<31=9 * (2 ^ 31) ,下面我们结合下图来看👇
    在这里插入图片描述

注:0 和 -2 ^ 31 相对

☝️如上图所示,对于int 类型(有符号整数)的x来说,其范围为:-2 ^ 31 ~ 2 ^ 31-1,当x=2 ^ 31 -1时,x+1将会变为-2 ^ 31,从而我们可以看出越界的本质就是转圈圈。此处1圈是2 ^ 32个数半圈是2 ^ 31 个数。所以9<<31=9* (2 ^ 31)=4.5* 2 ^ 32=4.5圈,去除整圈,得到0.5圈,从而结果是-2 ^ 31。怎么样,是不是很神奇?
👏当然,也可以通过取模来理解(其实补码的本质就是模运算),将原值与2 ^ 32 取模(因为1圈是2 ^ 32个数),得到2 ^ 31, 但有符号整数上界为2 ^ 31-1,再加一个数将会过渡到最小数 - (2 ^ 31).(此处是有向增加的)

2️⃣左移32位:

  • 1.从移位的角度来看
    • 第一步,左移32位:00000000 00000000 00000000 00000000(正)
    • 第二步,求出其原码:11111111 11111111 11111111 11111111+1=00000000 00000000 00000000 00000000❗️咦❓怎么是0啊❓上面的结果明明是9啊❗️怎么回事❓
      在这里插入图片描述

👉这就要考虑到位溢出了!我们上面说过了,C语言会将超出的位数进行取模操作,即将移位的位数对操作数的位数取模,然后进行相应的位移。因为如果直接移位的话,当移位长度大于31时必定是0;因为32>=32,所以32=0(mod(32)),从而原式的值等于00000000 00000000 00000000 00001001左移0位,也就是9本身。

mod可以理解为%运算;

  • 2.从值的角度来看

✨对于上面的9<<32,我们不能仅仅通过表面的移位去观察,而更应该计算一番。
👉因为9<<32=9*(2^32) ,所以原式就等于9圈,刚好是0。😄

3️⃣左移33位与左移32位类似,先对32取模再进行移位。此处不再赘述。


❤️无符号整数:

在这里插入图片描述
如上图,☝️

  • 无符号整数unsigned int 范围为 0~(2 ^ 32)-1,总共也是2 ^ 32个数,但都是非负数

(2 ^ 32 -1) +1 = 0 ,即结果要对2 ^ 32取模。

#include<stdio.h>int main(void)
{int a = 9;unsigned int b = a ;printf("%d\n", a << 31);printf("%u\n", b<<31);printf("%d\n", a << 32);printf("%u\n", b << 32);	return 0;
}

执行结果如下:
在这里插入图片描述

注:无符号十进制整数用%u输出;
计算方法根据上图转圈圈就好,此处不再赘述。


二、拓展应用:

1. 取模和位运算的转换:

x mod (2 ^ y) = x &((1<<y)-1) 即取x二进制表达后y位。(对于位与的操作可以参考前面的博文)

2. 生成标记码:

✨现将1<<k作为第k个标记位的标记码。(此处取从0开始)

(1. 标记位置1:

对于二进制数x,将它的第k位置为1.(从低位开始计位,即从右往左)

置1—>位或:x|(1<<k)

(2. 标记位置0:

对于二进制数x,将它的第k位置为0.(从低位开始计位,即从右往左)

置0—>位与:x&(1<<k) ,哦,不不不,不是这样的,应该是x&(~(1<<k))

(3. 标记位取反:

对于二进制数x,将它的第k位取反.(从低位开始计位,即从右往左)
取反—>异或:x^(1<<k)

3. 生成掩码:

✨我们可以通过左移来生成一个掩码,从而实现对一个数二进制表达的末k位执行一些操作。

  • 1<<k表示100…00(1加上k个0)
  • (1<<k)-1表示011111(0加上k个1)

从而可以进行以下操作:
🌟将末k位变为1:x|((1<<k)-1)
🌟将末k位变为0:x&(1<<k) x&(~((1<<k)-1))
🌟将末k位都取反:x^((1<<k)-1)


😵好了,今天的讲解就到这里了,相信你也是收获满满吧!

这真的我是肝的最久的一篇文章了,没有之一,从早上肝到了晚上,,,😭😭😭


在这里插入图片描述

相关文章:

【位运算进阶之----左移(<<)】

今天我们来谈谈左移这件事。 ❤️简单来说&#xff0c;对一个数左移就是在其的二进制表达末尾添0。左移一位添一个0&#xff0c;结果就是乘以2&#xff1b;左移两位添两个0&#xff0c;结果就乘以2 ^ 2&#xff1b;左移n位添n个0&#xff0c;结果就是乘以2 ^ n&#xff0c;小心…...

石油石化行业网络监控运维方案,全局态势感知,实时预警

石油石化行业是一个高科技密集型行业&#xff0c;投资巨大、人员众多&#xff0c;各产业价值链的关联度较高&#xff0c;大型石油石化企业实现了上中下游产业的一体化协同发展。随着工业4.0时代的来临&#xff0c;信息化和工业化融合&#xff0c;物联网、云计算等新技术的普及推…...

MyBatis 的关联关系配置 一对多,一对一,多对多 关系的映射处理

目录 一.关联关系配置的好处 二. 导入数据库表&#xff1a; 三. 一对多关系&#xff1a;-- 一个订单对应多个订单项 四.一对一关系&#xff1a;---一个订单项对应一个订单 五.多对多关系&#xff08;两个一对多&#xff09; 一.关联关系配置的好处 MyBatis是一…...

Diffusion Models for Image Restoration and Enhancement – A Comprehensive Survey

图像恢复与增强的扩散模型综述 论文链接&#xff1a;https://arxiv.org/abs/2308.09388 项目地址&#xff1a;https://github.com/lixinustc/Awesome-diffusion-model-for-image-processing/ Abstract 图像恢复(IR)一直是低水平视觉领域不可或缺的一项具有挑战性的任务&…...

Springboot开发所遇问题(持续更新)

SpringBoot特征&#xff1a; 1. SpringBoot Starter&#xff1a;他将常用的依赖分组进行了整合&#xff0c;将其合并到一个依赖中&#xff0c;这样就可以一次性添加到项目的Maven或Gradle构建中。 2,使编码变得简单&#xff0c;SpringBoot采用 JavaConfig的方式对Spring进行配置…...

智能电视与win10电脑后续无法实现DLNA屏幕共享

问题背景&#xff1a; 我用的是TCL电视&#xff0c;但是并不是最新&#xff0c;打开的方式是U盘->电脑&#xff0c;各位看自己情况&#xff0c;很多问题都大概率是智能电视问题。 情景假设&#xff1a; 假设你已经完成原先智能电视该有的步骤&#xff0c;通过DLNA&#xf…...

如何可以管理监督员工工作微信?

自从微信管理系统研发上线之后&#xff0c;为了各企业带来了福音。 很多用户企业都是这样评论微信管理系统的&#xff1a;员工的所有微信聊天记录后台都可以清楚明了的看到&#xff0c;聊天记录都是永久保存的&#xff0c;不担心员工在手机上把聊天记录删除&#xff0c;杜绝员…...

【Django】如何转化已有的数据表到Django模型--20230823

初步生成model.py $ python manage.py inspectdb $ python manage.py inspectdb > models.py python manage.py inspectdb # This is an auto-generated Django model module. # Youll have to do the following manually to clean this up: # * Rearrange models order…...

【C语言】喝汽水问题

大家好&#xff01;今天我们来学习C语言中的喝汽水问题&#xff01; 目录 1. 题目内容&#xff1a; 2. 思路分析 2.1 方法一 2.2 方法二 2.3 方法三 3. 代码实现 3.1 方法一 3.2 方法二 3.3 方法三 1. 题目内容 喝汽水&#xff0c;1瓶汽水1元&#xff0c;2个空瓶可以…...

项目进度管理(4-2)关键链法和关键路径法的区别和联系

1 关键链法和关键路径法的主要区别 1.1 关键链法和关键路径法的关注焦点不同 关键路径法&#xff08;CPM&#xff09;&#xff1a;关注项目中最长的路径&#xff0c;也就是所需时间最长的路径&#xff0c;这被称为关键路径。关键路径决定了项目的最早完成时间。关键链法&…...

基于Java+SpringBoot+Vue前后端分离医院后台管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…...

二维数组传参

在C语言中&#xff0c;可以通过指针来传递二维数组。二维数组实际上是一个连续的内存块&#xff0c;可以使用指针来表示二维数组的行和列。以下是一个示例&#xff1a; #include <stdio.h>void myFunction(int arr[][3], int rows) {for (int i 0; i < rows; i) {fo…...

AI 绘画Stable Diffusion 研究(十四)SD 图生图+剪映制作人物说话视频

大家好&#xff0c;我是风雨无阻。 前一篇&#xff0c;我们详细介绍了使用 SadTlaker制作数字人视频案例&#xff0c;感兴趣的朋友请前往查看:AI 绘画Stable Diffusion 研究&#xff08;十三&#xff09;SD数字人制作工具SadTlaker使用教程。 对于没有安装 SadTlaker 插件的朋友…...

ProPlot 基本语法及特点

文章目录 简介多子图绘制处理共享轴标签“跨度”轴标签多子图序号的绘制 更简单的颜色条和图例更加美观的颜色和字体 简介 科研论文配图多图层元素&#xff08;字体、坐标轴、图例等&#xff09;的绘制条件提出了更高要求&#xff0c;我们需要更改 Matplotlib 和 Seaborn 中的…...

element-template-admin get请求正常 post请求超市问题

最近搞全栈&#xff0c;想写个增删改查连接element-template-admin框架&#xff0c;postman测get和post请求都正常&#xff0c;到框架里直接超时&#xff0c;看网络请求一直是padding状态&#xff0c;后来经查阅资料&#xff0c;发现是这个template框架的问题 解决方案&#x…...

Promise.all和promise.race的应用场景举例

Promise.all( ).then( )适用于处理多个异步任务&#xff0c;且所有的异步任务都得到结果时的情况。 <template><div class"box"><el-button type"primary" plain click"clickFn">点开弹出框</el-button></div> &…...

go学习-指针 标识符

指针&#xff0c;以及标识符 1.指针 &#xff08;1&#xff09;.基本介绍 1&#xff09;基本数据类型&#xff0c;变量存的值&#xff0c;也叫值类型 2&#xff09;获取变量的地址用&&#xff0c;比如 var num int ,获取num的地址&#xff1a;&num 3)指针类型&…...

LeetCode--HOT100题(42)

目录 题目描述&#xff1a;108. 将有序数组转换为二叉搜索树&#xff08;简单&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;108. 将有序数组转换为二叉搜索树&#xff08;简单&#xff09; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xf…...

leetcode-49.字母异位词分组-day20

...

YOLOv8教程系列:三、K折交叉验证——让你的每一份标注数据都物尽其用(yolov8目标检测+k折交叉验证法)

YOLOv8教程系列&#xff1a;三、K折交叉验证——让你的每一份标注数据都物尽其用&#xff08;yolov8目标检测k折交叉验证法&#xff09; 0.引言 k折交叉验证&#xff08;K-Fold Cross-Validation&#xff09;是一种在机器学习中常用的模型评估技术&#xff0c;用于估计模型的性…...

leetcode算法题--表示数值的字符串

原题链接&#xff1a;https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/description/?envTypestudy-plan-v2&envIdcoding-interviews 题目类型有点新颖&#xff0c;有限状态机 // CharType表示当前字符的类型 // State表示当前所处的状态 type State…...

Docker安装及Docker构建简易版Hadoop生态

一、首先在VM创建一个新的虚拟机将Docker安装好 更新系统&#xff1a;首先打开终端&#xff0c;更新系统包列表。 sudo apt-get update sudo apt-get upgrade下图是更新系统包截图 安装Docker&#xff1a;使用以下命令在Linux上安装Docker。 sudo apt-get install -y docker.i…...

使用Burp Suite进行Web应用渗透测试

使用Burp Suite进行Web应用渗透测试是一种常见的方法&#xff0c;可以帮助发现Web应用程序中的安全漏洞和弱点。 步骤&#xff1a; 准备工作&#xff1a; 首先&#xff0c;确保已经安装了Burp Suite&#xff0c;并配置浏览器以使用Burp Suite作为代理。 配置代理&#xff1a;…...

Github的使用指南

首次创建仓库 1.官网创建仓库 打开giuhub官网&#xff0c;右上角点击你的头像&#xff0c;随后点击your repositories 点击New开始创建仓库 如下图为创建仓库的选项解释 出现如下界面就可以进行后续的git指令操作了 2.git上传项目 进入需上传项目的所在目录&#xff0c;打开…...

mongodb 添加加点 stateStr 停在 STARTUP

解决办法 PRIMARY 节点是的host 是否是内网IP&#xff0c;如果是内网IP 需要切换成外网IP 即可&#xff1b;...

c语言中编译过程与预处理

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、c语言的编译与链接1、编译与链接概述2、编译与链接详解 二、c语言预处理1.c语言中内置的预定义符号2、#define定义标识符3、#define定义宏4、#define 替换规…...

TP-LINK 路由器设置内网穿透

TP-LINK 路由器设置内网穿透 开发中经常遇到调用第三方软件回调调试的情况&#xff0c;例如微信开发&#xff0c;支付回调等测试&#xff0c;用内网穿透是一种简单的方式也是偷懒的方式。 以TP-LINK路由器为例实现内网穿透 登录路由器 2.找到路由器虚拟服务器&#xff0c;添加…...

A 题国际旅游网络的大数据分析-详细解析与代码答案(2023 年全国高校数据统计与调查分析挑战赛

请你们进行数据统计与调查分析&#xff0c;使用附件中的数据&#xff0c;回答下列问题&#xff1a; ⚫ 问题 1: 请进行分类汇总统计&#xff0c;计算不同国家 1995 年至 2020 年累计旅游总人数&#xff0c;从哪个国家旅游出发的人数最多&#xff0c;哪个国家旅游到达的人数最多…...

《深入理解Java虚拟机》读书笔记: 类加载器

类加载器 虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作放到Java虚拟机外部去实现&#xff0c;以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。 类加载器可以说是Java语言的一项创新&…...

宝塔计划任务读取文件失败

想挂计划任务 相关文章【已解决】计划任务读取文件失败 - Linux面板 - 宝塔面板论坛 对方反馈的是执行下面的命令 chattr -ai /var/spool/cron 后来发现直接没有这个文件夹&#xff0c;然后通过mkdir命令创建文件夹&#xff0c;成功在宝塔创建了计划任务 后面发现任务虽然添…...

公司网站建设 wordpress/百度投稿平台

有一种工作是经常要接触视频的&#xff0c;目前很多的视频平台对视频的要求还是很高的&#xff0c;有一个上传视频大小的限制&#xff0c;超过这个大小的视频无法正常进行发布&#xff0c;过大的视频需要压缩变小&#xff0c;下面介绍具体的压缩方法&#xff0c;&#xff0c;那…...

网站怎么做充值提现功能/苏州seo免费咨询

基本数据类型: 字符串: 字符串可以相加, 表示连接; 可以将字符串乘以某个数,表示将此字符串复制多少次. 数: 数的加减乘除取余等. 需要注意的是两个乘号**和两个除号/ / python2中的除法和3有所不同&#xff0c;那么需要import math &#xff0c;然后使用math方法来达到和…...

页面模板 公众号/seo关键词优化排名哪家好

7、约束&#xff08;非常重要&#xff0c;五颗星*****&#xff09; 7.1、什么是约束&#xff1f; 约束对应的英语单词&#xff1a;constraint 在创建表的时候&#xff0c;我们可以给表中的字段加上一些约束&#xff0c;来保证这个表中数据的 完整性、有效性&#…...

哪个网站可以领单做效果图/当日网站收录查询统计

在企业中&#xff0c;会有多人使用同一个exchange邮箱的情况&#xff0c;这些人在自己的机器上配置outlook客户端&#xff0c;使用MAPI协议连接到exchange 2010.默认outlook MAPI方式连接exchange服务器&#xff0c;最大的session数为16个&#xff0c;超过16个用户同时使用一个…...

惠民建设局网站是哪个/友情链接大全

使用python请求服务器 可以查看header信息是这样的&#xff1a; Host: 127.0.0.1:3369 User-Agent: python-requests/3.21.0 Accept-Encoding: gzip, deflate Accept: / Connection: keep-alive很明显暴露了你不是普通用户&#xff0c;容易被封&#xff0c;所以需要把自己伪装…...

建设网站所采用的技术方案/产品网络营销推广方案

2019独角兽企业重金招聘Python工程师标准>>> 因為前陣子跟朋友們一起弄了一個以 web / mobile development 為主題的 weekly&#xff0c;每個禮拜在考慮要放哪些內容的時候&#xff0c;突然覺得&#xff1a;「你都去哪裡看技術文章&#xff1f;」或許也會是個有價值…...