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

这篇具有很好参考价值的文章主要介绍了位运算(按位与、按位或、异或、取反)以及原码、反码、补码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

位运算

按位与运算符 [ & ]

按位或运算符 [ | ]

异或运算符 [ ^ ]

取反运算符 [ ~ ]

移位操作

一些面试常考的位操作运算

获取二进制中最右边的1

计算机原码、反码、补码

机器数

“三码”之间的转换

计算机中为啥要用补码呢?

真数

原码

反码

补码

有了原码为什么要使用反码和补码

位运算

按位与运算符 [ & ]

运算规则:依次比较两个二进制数的每一位,全部为1则为1,否则为0的规则,依次计算出一个新的二进制数:

即:0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1
例: 39 & 21 --> 0010 0111 & 0001 0101 --> 0000 0101

按位或运算符 [ | ]

运算规则:依次比较两个二进制数的每一位,只要有一个为1则为1,否则为0的规则,依次计算出一个新的二进制数:

即:0 | 0= 0 ,0 | 1= 1,1 | 0= 1, 1 | 1= 1

例: 39 | 21 --> 0010 0111 | 0001 0101 --> 0011 0111

异或运算符 [ ^ ]

运算规则:依次比较两个二进制数的每一位,按照相同为0,不同为1的规则,依次计算出一个新的二进制数:

即:0 ^ 0= 0 ,0 ^ 1= 1,1 ^ 0= 1, 1 ^ 1= 1
例: 39 ^ 21 --> 0010 0111 ^ 0001 0101 --> 0011 0010

取反运算符 [ ~ ]

运算规则:对于二进制数的每一位,1变0,0变1,得到一个新的二进制数:

即:~0 = 1 , ~1= 0
因为涉及到、补码、原码、符号,感觉挺复杂的,涉及的知识比较多,总结为一句:

对所有整数取反=本身的相反数减一
~9 = -10
~10 = -11

移位操作

<<: 左移、>> : 右移
箭头指向哪就是向哪移。左移之后右边补0,右移之后在左边补0

结论: 对于正数而言,其实左移和右移n位就相当于乘以或者除以2的n次方。

比如:十进制的5,该数二进制为 0000 0101,将该数左移3为
结果为0010 1000,转换成十进制为 40, 验证了上面的结论:5左移三位就等于5乘以2的三次方等于40。
再比如:十进制的40,右移三位就相当于除以8(2的三次方)结果为5。
那么问题来了,有一个数a,有一个数b,我要让b等于a的第三位,怎么算。

思路:先让a右移俩位,那么a原来的第三位现在就变成最后一位,再让移后的数和1想与,结果即为a原来的第三位。

一些面试常考的位操作运算

去掉最后一位 | (101101->10110) | 				x >> 1
在最后加一个0 | (101101->1011010) | 				x << 1
在最后加一个1 | (101101->1011011) |				x << 1+1
把最后一位变成1 | (101100->101101) | 			x | 1
把最后一位变成0 | (101101->101100) | 			x | 1-1
最后一位取反 | (101101->101100) | 				x ^ 1
把右数第k位变成1 | (101001->101101,k=3) | 		x | (1 << (k-1))
把右数第k位变成0 | (101101->101001,k=3) | 		x & ~ (1 << (k-1))
右数第k位取反 | (101001->101101,k=3) | 			x ^ (1 << (k-1))
取末三位 | (1101101->101) | 						x & 7
取末k位 | (1101101->1101,k=5) | 				x & ((1 << k)-1)
取右数第k位 | (1101101->1,k=4) | 				x >> (k-1) & 1
把末k位变成1 | (101001->101111,k=4) | 			x | (1 << k-1)
末k位取反 | (101001->100110,k=4) | 				x ^ (1 << k-1)
把右边连续的1变成0 | (100101111->100100000) | 	x & (x+1)
把右起第一个0变成1 | (100101111->100111111) | 	x | (x+1)
把右边连续的0变成1 | (11011000->11011111) |   	x | (x-1)
取右边连续的1 | (100101111->1111) | 				(x ^ (x+1)) >> 1
去掉右起第一个1的左边 | (100101000->1000) |   	x & (x ^ (x-1))
判断奇数 										(x&1)==1
判断偶数 										(x&1)==0 
取右边第一个1所在位置 							x&-x

获取二进制中最右边的1

x&(-x)
就是这么简洁,就能实现获取到二进制中最右边的 1,且其它位设置为 0。

原因:
首先在补码表示法中,负数的补码 = 取反 +1,这个都知道,但你可能没发现:
取反后:最右边的 0 的位置对应于 最右边的 1 的位置,
而取反后 +1 ,则会把该位的1往前进位(同时该位也会恢复为0),直到遇到第一个0停止,并把此位置为1,而第一个0就恰恰对应第一个1。

所以负数的补码则相当于将最右边的 1 的左边的所有位取反

如图

按位与怎么计算,C语言,c语言,计算机基础
到这已经很显然了,x 和 −x 只有一个共同点:最右边的 1
(其实这么说是不严谨的,因为最右边的1起,该位右边的0也是相同的,只是对操作没影响)

因此 x & (-x) 将保留最右边的 1。并将其他的位设置为 0。

计算机原码、反码、补码

机器数

一个数在计算机中的表现形式叫做机器数,这个数有正负之分,在计算机中用一个数的最高位(符号位)用来表示它的正负,其中0表示正数,1表示负数。

例如正数7,在计算机中用一个8位的二进制数来表示,是00000111,而负数-7,则用10000111表示,这里的00000111和10000111是机器数

“三码”之间的转换

注意:以下的分析均以 1字节 进行

正数 负数
原码 数据的二进制形式 数据的二进制形式
反码 等于原码 原码的符号位不变,其他位取反
补码 等于原码 负数的反码“+1”

 注意:无符号数,正数,它们的 原码=反码=补码
负数: 反码=原码的符号位不变,其他位取反
补码:反码+1.

重要:负数在计算机中存储的是补码。

计算机中为啥要用补码呢?

  • 1,将减法运算变为加法运算:

就拿6-10==-4来举个例子:
如果没有补码,则计算如下:
6 + (-10) = -4
0000 0110
+1000 1010

--------------------
1001 0000 = -16 (则计算结果错误)

如果有补码:
0000 0110
1111 0110(- 10的补码)
-----------------
1111 1100(-4的补码)——>1000 0011——>1000 0100== -4
在上述补码的计算中我们也可以得出一个负数由补码到原码的计算方法:“原码 = 补码取反+1”

真数

计算机中的机器数对应的真实的值就是真数,对最高位(符号位)后面的二进制数转换成10进制,并根据最高位来确定这个数的正负。对于上面的00000111和10000111来说,对最高位后面的二进制数转换成10进制是7,在结合最高位的值,得出对应的真数分别是7和-7

原码

用第一位表示符号,其余位表示值。因为第一位是符号位,所以8位二进制数的取值范围就是:[1111_1111 , 0111_1111] 即 [-127 , 127] ,原码是容易被人脑所理解的表达方式

反码

正数的补码反码是其本身,负数的反码是符号位保持不变,其余位取反。例如正数1的原码是[0000_0001],它的反码是是其本身

[0000_0001],-1的原码是[1000_0001],其反码是[1111_1110]

补码

正数的补码是其本身,负数的补码是在其反码的基础上+1,例如正数1的原码是[0000_0001],他的补码是其本身[0000_0001],

-1的补码是[1111_1111]

有了原码为什么要使用反码和补码

因为人脑可以知道第一位是符号位,可以根据符号位对真值的绝对值进行加减乘除,但是对于计算机来说,加减乘除是最最最基本的运算,要设计的尽量简单,计算机辨别符号位会让计算机的设计电路变得很复杂,于是人们想出了让符号位也参与到运算上来。减去一个数,等于加上他的负数

使用原码参数运算的缺陷
按位与怎么计算,C语言,c语言,计算机基础

从上面的原码表中可以看见左边每增加一个二进制单位对应的真数是递减的,而右边每增加一个二进制单位对应的真数是递增的,所以对于原码来说,能满足正数的加法,但无法满足负数的加法

2+1 = [0000_0010]原+[0000_0001]原=[0000_0011]原 = 3

±1=[0000_00001]原+[1000_0001]原=[1000_0010]原=-2

为了满足负数对加法的需求,就必须让负数与他对应的二进制码是同步递增或者同步递减

于是就通过符号位不变,其余位取反来满足这个同步递增或者递减的要求,由于正数本来就满足它本身的加法,所以不需要做任何改变。这就是反码的定义由来。
按位与怎么计算,C语言,c语言,计算机基础

从上图的反码表中可以看到在运算不跨过0的时候,正负数的加法已经能满足要求

-2+1=[1111_1101]反+[0000_0001]反=[1111_1110]反=-1

127+1=[1000_0000]反=-127=128 加法算出来是128,由于128超过最大值,余1,所以取最小值开始的第一位,也就是

最小值-127,但是这里有个不合理的地方,就是[1111_1111]和[0000_0000]都表示0,这导致在实际计算中每当跨过0一次,就有一个单位的误差

-1+2=[1111_1110]反+[0000_0010]反=[0000_0000]反=0

要解决这个问题就必须让反码中的[1111_1111]和[0000_0000]合并,

由于[1111_1111]+[0000_0001]=[0000_0000],所以在负数反码的基础上+1就可以解决反码中跨0的误差问题,同时不会对负数与它对应的二进制反码的同步递增产生影响,所以在反码的基础上+1就完美的解决了符号参与预算的问题,这就是补码为什么是在负数反码的基础上+1的由来。

 按位与怎么计算,C语言,c语言,计算机基础

 从上面的图中发现还有一个[1000_0000]的二进制没有对应任何真数,于是就规定了这个数的真数是-128

所以补码的表示范围是[-128~127] ,这样一来256个二进制正好表示256个整数,在实际二进制的运算中超过范围其实就是对256的取余预算(x+128)mod 256 - 128。文章来源地址https://www.toymoban.com/news/detail-787624.html

到了这里,关于位运算(按位与、按位或、异或、取反)以及原码、反码、补码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 关于二进制的原码、补码和反码,以及表示范围、常见位运算符和进制转换的理解与简述

    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/17963363 出自【进步*于辰的博客】 参考笔记一,P3.13、P5.1;笔记三,P43.1/3、P44.1。 注:我暂且没有整理关于二进制、原码、补码和反码等概念的理论,本文中的阐述都基于

    2024年02月02日
    浏览(46)
  • 【C语言】中的位操作符和移位操作符,原码反码补码以及进制之间的转换

    欢迎大家来到c语言知识小课堂,今天的知识点是操作符和进制 同样都是数字1111,不同进制下数字的大小不同,第二行代表的是其各位数字十进制下的大小,将各位数字的十进制大小相加即1111在这个进制下转化为十进制的大小,从图中我们可以看出来 进制的定义:从右往左

    2024年02月22日
    浏览(52)
  • 爱上C语言:整型和浮点型在内存中的存储(进制转换,原码,反码,补码以及大小端)

    🚀 作者:阿辉不一般 🚀 你说呢: 生活本来沉闷,但跑起来就有风 🚀 专栏:爱上C语言 🚀 作图工具:draw.io ( 免费开源的作图网站) 如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主,如有不足还请指点,博主及时改正,感谢大家支持!!! 大家好啊😉!今

    2024年02月05日
    浏览(55)
  • 原码,反码,补码,移码

    原码、反码、补码和移码是在计算机中表示有符号整数的方法。它们是为了处理正负数的运算和表示而设计的。下面我会逐个解释这些概念,并说明它们的使用和理解。 原码(Sign-Magnitude Representation): 原码是最简单的表示方法,其中最高位表示符号(0代表正数,1代表负数

    2024年02月08日
    浏览(38)
  • 原码,反码,补码

            原码、反码和补码是计算机中表示有符号整数的三种不同的二进制表示形式。它们的理解和原理涉及了计算机内部整数表示的数学概念和编码规则。 十进制数 原码 反码 补码 +5 00000101 00000101 00000101 +4 00000100 00000100 00000100 +3 00000011 00000011 00000011 +2 00000010 00000010 0000001

    2024年02月15日
    浏览(41)
  • 什么是原码、反码和补码

    前言 一个数在计算机中的表示形式是二进制的话,这个数其实就叫机器数。 机器数通常是带有符号的(指有正数和负数之分),计算机用最高位存放符号,这个 bit 一般叫做符号位。 正数的符号位为 0, 负数的符号位为 1。比如,十进制中的数 +7 ,计算机字长为8位,转换成

    2023年04月09日
    浏览(37)
  • 原码、补码、反码的关系及应用场景

    是三种表示有符号整数的方法,它们之间存在一定的关系。 原码 是最基本的表示方法,即将一个数的符号位和数值位分开表示,符号位用0表示正数,用1表示负数。例如,+7的原码为00000111,-7的原码为10000111。 反码 是在原码的基础上,将负数的数值位按位取反得到的表示方

    2024年02月06日
    浏览(47)
  • List 3.5 详解原码、反码、补码

    本博客文章已收录至我的Java SE专栏,如需阅读其他有关博客笔记请转至该专栏下 传送门 --Java SE_程序员雨空集 目录  前言 原码 原码的示例 原码的弊端 反码 反码的示例 反码的弊端 补码 补码的示例 补码的小细节 总结 原码:十进制数据的二进制表现形式,最左边是符号位,

    2024年02月08日
    浏览(98)
  • C++知识精讲13 | 原码、反码和补码

    ------------------------------------------------------------------------------------------------------------------------- 观看视频ing......  12岁的少年编程者告诉你编程如此简单  ------------------------------------------------------------------------------------------------------------------------- ---------------------------------------

    2024年02月16日
    浏览(37)
  • 【教3妹学编程-算法题】检查按位或是否存在尾随零

    3妹 :呜呜,烦死了, 脸上长了一个痘 2哥 : 不要在意这些细节嘛,不用管它,过两天自然不就好了。 3妹 :切,你不懂,影响这两天的心情哇。 2哥 : 我看你是不急着找工作了啊, 工作那么辛苦,哪还有时间想这些啊。 3妹 :说到找工作,我又要去刷题了。 2哥 :我给你出

    2024年01月20日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包