【位运算进阶之----右移(>>)】

😄嘻嘻,朋友们,大家好!昨天我们学习了左移,今天我们来谈谈右移>>。


⭐️简单来说,右移就是将一个数二进制表达整体向右移动,也就是去掉一个数的二进制表达的末位,右移一位就去掉一位,右移两位就去掉两位。一般情况下右移就是除以2的幂并向下取整。

下面就让我们来详细看看吧!

在这里插入图片描述


文章目录

  • 一、基础知识
    • 1️⃣ 右移的二进制表示:
    • 2️⃣ 右移的执行结果:
    • 3️⃣ 对负数右移:-x>>y=-⌈(x>>y)⌉(不建议用)
      • 1. -9>>1
      • 2. ((unsigned int)-9) >> 2
    • 4️⃣ 右移负数位:
  • 二、拓展应用:
    • 1. 去除低k位:
    • 2. 取第k位的值:
  • 三、写在后面的话:


一、基础知识

✨右移运算符是一个二元运算符,右移操作是也一种位操作,用来将一个数的二进制表达所有位向右移动指定的位数

✨我们知道,无符号整数都是非负数,所以负数只出现在有符号整数中。(所以我们这里可以不分有符号整数和无符号整数):

  • 对于正数直接右移(左侧添0,可视为不添)
  • 对于负数右移后左侧添1;0你懂的

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

✨x>>y 表示将x的二进制表达向右移动y位(其中x和y都是整数)。
如:1001 >> 2 ----> 10 (直接去掉后两位)


2️⃣ 右移的执行结果:

✨右移操作相当于将一个数除以2的n次方
x>>y <=> [ x 2 y \frac {x}{2^y} 2yx] ,方括号一般认为是向下取整。咦?不是常说右移是除以2,左移是乘以2吗,你这怎么还向下取整了呢?
在这里插入图片描述
👉因为不是所有的数都能被2整除,所以根据C语言右移的规则,应当向下取整。(C语言除法结果是正数则向下取整,结果为负数则向零取整)
在这里插入图片描述

  • 所以上面的1001>>2 = [ 9 2 2 \frac {9}{2^2} 229] = [ 9 4 \frac {9}{4} 49] = 2(向下取整)

代码如下:

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

执行结果如下:

在这里插入图片描述
可以看出结果是9/4=2;
下面我们继续增大右移的位数:

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

在这里插入图片描述
可以看出9/16=0,没什么问题。

  • 当然,这里也可以从补码(移位)的角度来解释。9的二进制表达一共4位有效,向右移动4位后显然是0。

3️⃣ 对负数右移:-x>>y=-⌈(x>>y)⌉(不建议用)

注:-x>>y并不等于-(x>>y)

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

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

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

我们先来看a,a是一个有符号整数-9,现在对其右移。

1. -9>>1

  • (1)值的角度:
    -9>>1 = [-9/2] = [-4.5] = -5 (向下取整),但-(9>>1)=-([9/2])=-4
    注意:这里千万要和-9/2 = -4区分开来!因为在C语言中,对于负数的取整通常是向零取整(向上取整)。也就是说,负数会被取整为最接近且大于等于它的整数。
    如:(int)(-3.9) = -3 ;(int)(-2.1) = -2;

对应的符合见下图,左面是向下取整,右面是向上取整:
在这里插入图片描述
下面是它们的图像:

❤️向下取整(高斯函数):
在这里插入图片描述
❤️向上取整:
在这里插入图片描述
这里我就不展开讨论了,以后有机会再深入去了解其二者的相关知识。

  • (2)补码的角度:
    • 9的补码是:00000000 00000000 0000000 00001001
    • -9的补码是:11111111 11111111 11111111 11110110 + 1-->11111111 11111111 11111111 11110111
    • -9的补码右移一位:11111111 11111111 11111111 11111011(左侧补1)
    • 转换成机器数(原码):10000000 00000000 00000000 00000100+1-->10000000 00000000 00000000 00000101 = -5

😄综上我们得到了-x>>y = -⌈(x>>y)⌉ = -(⌈ x 2 y \frac {x}{2^y} 2yx⌉),注意,此处是向上取整,但计算机中默认正整数除法是向下取整,所以你可能要用ceil函数自己处理。

-9>>2,-9>>3与上面的推理过程类似,此处不再赘述!


2. ((unsigned int)-9) >> 2

  • 现在,就让我们来看看上图的最后一个输出,为什么是1073741821呢?

在这里插入图片描述
✨首先,b的类型是unsigned int ,无符号整型,也就是都是非负的。现在我们执行第一个语句:b=a , 将-9赋值给一个无符号整型,b的值将会变成多少呢?这里我们借助昨天的图来进行求解:👇
在这里插入图片描述
✨如何求b的值,言下之意就是让我们从0开始往左数9个数,可以轻松得到b的值是2 ^ 32-9,也就是4294967296-9=4294967287
✨现在,我们得到了((unsigned int)-9) >> 2 <=> 4294967287>>2,下面从两个方面进行求解:

  • (1)值的角度:然后另b除以4并向下取整,即[4294967287/4]=4294967287/4=1073741821
  • (2)移位的角度:
    1. 因为2 ^ 32-1的二进制表达是:11111111 11111111 11111111 11111111
    2. 所以2 ^ 32-9的二进制表达可以写为:11111111 11111111 11111111 11111111-00000000 00000000 00000000 00001000=11111111 11111111 11111111 11110111
    3. 现对其右移两位:00111111 11111111 11111111 11111101,然后将其以十进制的形式输出即可。

验证一下输出:

#include<stdio.h>int main(void)
{int b = 0b00111111111111111111111111111101;printf("%d", b);return 0;
}

执行结果如下:
在这里插入图片描述
执行结果正确,证明上述解法可行。


4️⃣ 右移负数位:

✨昨天我们了解了左移负数位的情况,发现那是未定义的行为,现在我们来看看右移负数位又会如何?let's go!!!
在这里插入图片描述
我们先来看一段代码:

#include<stdio.h>int main(void)
{int a = 9;printf("%d\n", a >>  0);printf("%d\n", a >> -1);printf("%d\n", a >> -2);printf("%d\n", a >> -3);return 0;
}

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

💔咦❓这个输出有点意思,到底是怎么回事呢❓右移负数位竟然没有报错,那就是合理的❓既然合理,那为啥会出现这种结果呢❓按照我们以往的思维,右移-1位就是左移1位啊❗️结果不应该是18吗,怎么不对呢❓阁下莫急,我们接着往下看:

#include<stdio.h>int main(void)
{int a = 9;printf("%d\n", a >>  0);printf("%d\n", a >> -1);printf("%d\n", a >> -2);printf("%d\n", a >> -3);printf("***\n");printf("%d\n", a >> -30);printf("%d\n", a >> -31);printf("%d\n", a >> -32);printf("%d\n", a >> -33);printf("%d\n", a >> -34);printf("%d\n", a >> -35);return 0;
}

执行效果如下:
在这里插入图片描述
💔咦?下面这个结果也有点出乎意料啊!9>>-30结果是2❗️9>>-32结果是9❗️相信如果你对数字比较敏感的话,应该已经发现了右移负数位的规律。当然,如果没有发现也不用着急,我们继续往下看:

#include<stdio.h>int main(void)
{int a = 9;printf("%d\n", a >>  0);printf("%d\n", a >> -1);printf("%d\n", a >> -2);printf("%d\n", a >> -3);printf("***\n");printf("%d\n", a >> -30);printf("%d\n", a >> -31);printf("%d\n", a >> -32);printf("%d\n", a >> -33);printf("%d\n", a >> -34);printf("%d\n", a >> -35);printf("***\n");printf("%d\n", a >> -62);printf("%d\n", a >> -63);printf("%d\n", a >> -64);printf("%d\n", a >> -65);printf("%d\n", a >> -66);printf("%d\n", a >> -67);return 0;
}

在这里插入图片描述
❤️通过第三个代码我们可以看出:
🌟右移-32位的倍数的时候和右移0位时类似,都是其本身;
🌟右移-30位和右移-62位类似,都是2,那2又有什么特殊之处呢?我们来看看它们的补码:

  • 9的原(补)码是:00000000 00000000 00000000 00001001
  • 2的原(补)码是:00000000 00000000 00000000 00000010

可以看出,9>>2 = 2,且32-(abs(-30)%32)=232- (abs(-62)%32)=2

🌟右移-31位和右移-63位类似,都是4

  • 4的原(补)码是:00000000 00000000 00000000 00000100

我们知道9>>1 = 4,且32-(abs(-31)%32)=132- (abs(-63)%32)=1

所以,经过上述的推导我们可以得出右移负数位的计算公式:
若记右移n位(n为负数),并记结果为result,则
result=32-(abs(n)%32)

(此为博主自己总结的结论,如有错误还请指正,如需引用还请注明出处)

当然,右移负数位在平常很少用到(一般都在一定范围内左移或右移,别自己给自己找麻烦)。


二、拓展应用:

✨下面的第k位均为从右往左第k位(从第0位开始数),如果习惯按第1位开始,则可令k=k+1;

1. 去除低k位:

给定一个数x,将其低k位去除后再输出。
方法:直接右移k位即可,x>>k

2. 取第k位的值:

二进制表达只有0或1,所以第k位要么是0,要么是1。
方法:将x右移k位后 和1位于 or 和0位或
(x>>k)&1 or (x>>k)|0

  • 除此之外,还有其他的一些操作,都可以通过位运算的相关定义得出,此处不再赘述!

三、写在后面的话:

🔥自从chatgpt等大语言模型出现之后,立刻就有了相当广泛的应用。不论是商用还是民用,像是平常询问零碎的知识点,聊天,写代码等等,都有了其一席之地。不可否认,它们的确很强大。但随着其进一步发展,就拿CSDN平台来说,无论是问答还是写博客,都或多或少地存在着它们的影子。

🔥先说写博客方面,过分依赖于gpt写的博客和人写的博客其实差异还是蛮大的,因为前者写的大都比较生硬,基本以大片大片的概念为主,缺乏和观者的互动;并且其所述的知识也不一定都是正确的,所以我想说什么,你懂的。

🔥再说问答方面,我无法忍受一个外行人完全借助gpt来回答各行各业的问题,你回答对了我不说什么,但你完全借其所答,拿着错误的答案去回复别人,这既是一种对问者的不尊敬,也是对自己行为的不负责。我认为,它应该成为一种提升自己能力的工具,而不是将其信奉为教条,它可以用来验证我们的想法,也可以帮我们打开思路,但唯独不能代替我们。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


好了,今天的讲解就到这里了,相信你也是收获满满吧!接下来我将会开专栏讲解数据结构和算法Python等相关知识,希望对你能有所帮助!


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/56305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kaniko在containerd中无特权快速构建并推送容器镜像

目录 一、kaniko是什么 二、kaniko工作原理 三、kanijo工作在Containerd上 基于serverless的考虑&#xff0c;我们选择了kaniko作为镜像打包工具&#xff0c;它是google提供了一种不需要特权就可以构建的docker镜像构建工具。 一、kaniko是什么 kaniko 是一种在容器或 Kube…

字符集(Latin1,GBK,utf8,utf8mb4)

Latin1 1个字符占一个字节GBK 1个字符占两个字节utf8utfmb3 1个字节占三个字节utf8mb4 1个字符占四个字节

前端(十五)——GitHub开源一个react封装的图片预览组件

&#x1f475;博主&#xff1a;小猫娃来啦 &#x1f475;文章核心&#xff1a;GitHub开源一个react封装的图片预览组件 文章目录 组件开源代码下载地址运行效果展示实现思路使用思路和api实现的功能数据和入口部分代码展示 组件开源代码下载地址 Gitee&#xff1a;点此跳转下载…

Java入职第十一天,深入了解静态代理和动态代理(jdk、cglib)

一、代理模式 一个类代表另一个类去完成扩展功能,在主体类的基础上,新增一个代理类,扩展主体类功能,不影响主体,完成额外功能。比如买车票,可以去代理点买,不用去火车站,主要包括静态代理和动态代理两种模式。 代理类中包含了主体类 二、静态代理 无法根据业务扩展,…

C++Qt堆叠窗体的使用案例

本博文源于笔者最近学习的Qt&#xff0c;内容讲解堆叠窗体QStackedWidget案例&#xff0c;效果是选择左侧列表框中不同的选项时&#xff0c;右侧显示所选的不同的窗体。 案例效果 案例书写过程 控件都是动态创建的&#xff0c;因此.h文件需要创建控件&#xff0c;.cpp书写业务…

四层负载均衡的NAT模型与DR模型推导 | 京东物流技术团队

导读 本文首先讲述四层负载均衡技术的特点&#xff0c;然后通过提问的方式推导出四层负载均衡器的NAT模型和DR模型的工作原理。通过本文可以了解到四层负载均衡的技术特点、NAT模型和DR模型的工作原理、以及NAT模型和DR模型的优缺点。读者可以重点关注NAT模型到DR模型演进的原…

vue table合并行 动态列名

需求: 1.合并行,相同数据合并 2,根据后端返回数据动态显示列名, 我这个业务需求是,每年增加一列,也就是列名不是固定的,后端返回数据每年会多一条数据,根据返回数据显示列名 实现: html <el-table v-loading"loading" :data"dataList" :span-metho…

视频汇聚平台EasyCVR安防视频监控平台新增经纬度选取功能的详细介绍

视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同&#xff0c;支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强&#xff0c;视频能力丰富&#xff0c;具体可实现视频监控直播、视频轮播、视频录像、…

ios ipa包上传需要什么工具

目录 ios ipa包上传需要什么工具 前言 一、IPA包的原理 二、IPA包上传的步骤 1.注册开发者账号 2.apk软件制作工具创建应用程序 3.构建应用程序 4.生成证书和配置文件 5.打包IPA包 6.上传IPA包 三、总结 前言 iOS IPA包是iOS应用程序的安装包&#xff0c;可以通过iT…

12. Oracle中case when详解

格式&#xff1a; case expression when condition_01 then result_01 when condition_02 then result_02 ...... when condition_n then result_n else result_default end 表达式expression符合条件condition_01&#xff0c;则返回…

性能测试流程? 怎么做性能测试?

一、前期准备 性能测试虽然是核心功能稳定后才开始压测&#xff0c;但是在需求阶段就应该参与&#xff0c;这样可以深入了解系统业务、重要功能的业务逻辑&#xff0c;为后续做准备。 二、性能需求分析&#xff08;评审&#xff09; 评审时&#xff0c;要明确性能测试范围、目…

[足式机器人]Part3机构运动微分几何学分析与综合Ch03-1 空间约束曲线与约束曲面微分几何学——【读书笔记】

本文仅供学习使用 本文参考&#xff1a; 《机构运动微分几何学分析与综合》-王德伦、汪伟 《微分几何》吴大任 Ch01-4 平面运动微分几何学 3.1 空间曲线微分几何学概述3.1.1 矢量表示3.1.2 Frenet标架 连杆机构中的连杆与连架杆构成运动副&#xff0c;该运动副元素的特征点或特…

一文搞懂深度信念网络!DBN概念介绍与Pytorch实战

目录 一、概述1.1 深度信念网络的概述1.2 深度信念网络与其他深度学习模型的比较结构层次学习方式训练和优化应用领域 1.3 应用领域图像识别与处理自然语言处理推荐系统语音识别无监督学习与异常检测药物发现与生物信息学 二、结构2.1 受限玻尔兹曼机&#xff08;RBM&#xff0…

正确进行自动化测试

前言&#xff1a; &#x1f4d5;作者简介&#xff1a;热爱编程的小七&#xff0c;致力于C、Java、Python等多编程语言&#xff0c;热爱编程和长板的运动少年&#xff01; &#x1f4d8;相关专栏Java基础语法&#xff0c;JavaEE初阶&#xff0c;数据库&#xff0c;数据结构和算法…

10-案例: 注册登录

项目思路: 1. 首页展示 将数据传递给前端模板渲染 2. 注册用户 接收前端传递的数据,保存后,重定向到首页 3. 删除用户 接收前端传递的用户名,进行删除 4. 修改用户 接收前端传递的数据,老名字进行判断,新数据修改数据 项目结构: 构建蓝图: (1). apps / user / model.py 增…

边写代码边学习之Bidirectional LSTM

1. 什么是Bidirectional LSTM 双向 LSTM (BiLSTM) 是一种主要用于自然语言处理的循环神经网络。 与标准 LSTM 不同&#xff0c;输入是双向流动的&#xff0c;并且它能够利用双方的信息。 它也是一个强大的工具&#xff0c;可以在序列的两个方向上对单词和短语之间的顺序依赖…

react通过ref获取函数子组件实例方法

在react16之后带来了hooks之后&#xff0c;确实方便了很多组件开发&#xff0c;也加快了函数式编程的速度&#xff0c;但是当你通过useRef获取子组件的时候&#xff0c;又恰好子组件是一个函数组件&#xff0c;那么将会报一个错误&#xff1a;报这个错误的主要原因是函数组件没…

数据通信——传输层(UDP)

引言 我们上网观看比赛的时候&#xff0c;一旦网络信号出现问题&#xff0c;那可就太难受了&#xff0c;这意味着卡顿的时间内&#xff0c;你会错过这段时间内的内容。这种特性要归功于UDP&#xff08;User Datagram Protocol&#xff09;用户数据报协议。 无连接性 一般的&am…

第十七课:利用 Setup Factory 制作 Qt 软件安装包

功能描述&#xff1a;详细介绍如何利用 Setup Factory 制作 Qt 软件安装包&#xff0c;从 Setup Factory 软件下载、安装&#xff0c;到如何利用 Setup Factory 制作软件安装包&#xff0c;手把手教你将 Qt 应用程序制作成具有安装向导的安装包。 一、Setup Factory 简介 Setu…

qt信号槽同步问题

目录 信号槽&#xff1a; 注意事项&#xff1a; 具体例子&#xff1a; 线程安全问题的例子&#xff1a; 信号槽&#xff1a; 在Qt编程中&#xff0c;信号&#xff08;Signal&#xff09;和槽&#xff08;Slot&#xff09;是一种用于在对象之间进行通信的机制。信号用于发出…