大型网站建设机构,网络推广项目,上海官网制作,郑州网站排名哪家好参考#xff1a;运算符的计算#xff08;按位与 按位或 异或 取反#xff09; 作者#xff1a;一只青木呀 发布时间#xff1a; 2020-07-23 18:13:55 网址#xff1a;https://blog.csdn.net/weixin_45309916/article/details/107543919 参考#xff1a;计算机原码#… 参考运算符的计算按位与 按位或 异或 取反 作者一只青木呀 发布时间 2020-07-23 18:13:55 网址https://blog.csdn.net/weixin_45309916/article/details/107543919 参考计算机原码反码补码 作者chenchao2017 发布时间 2018-04-03 10:22:38 网址https://blog.csdn.net/chenchao2017/article/details/79733278?utm_mediumdistribute.pc_relevant_t0.none-task-blog-searchFromBaidu-1.controldepth_1-utm_sourcedistribute.pc_relevant_t0.none-task-blog-searchFromBaidu-1.control 目录位运算按位与运算符 [ ]按位或运算符 [ | ]异或运算符 [ ^ ]取反运算符 [ ~ ]移位操作一些面试常考的位操作运算计算机原码、反码、补码机器数真数原码反码补码有了原码为什么要使用反码和补码位运算
按位与运算符 [ ]
运算规则依次比较两个二进制数的每一位全部为1则为1否则为0的规则依次计算出一个新的二进制数
即0 0 0 0 1 01 0 0 1 1 1 例 39 21 -- 0010 0111 0001 0101 -- 0000 0101
按位或运算符 [ | ]
运算规则依次比较两个二进制数的每一位只要有一个为1则为1否则为0的规则依次计算出一个新的二进制数
即0 | 0 0 0 | 1 11 | 0 1 1 | 1 1 例 39 | 21 -- 0010 0111 | 0001 0101 -- 0011 0111
异或运算符 [ ^ ]
运算规则依次比较两个二进制数的每一位按照相同为0不同为1的规则依次计算出一个新的二进制数
即0 ^ 0 0 0 ^ 1 11 ^ 0 1 1 ^ 1 1 例 39 ^ 21 -- 0010 0111 ^ 0001 0101 -- 0011 0010
取反运算符 [ ~ ]
运算规则对于二进制数的每一位1变00变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右移三位就相当于除以82的三次方结果为5。 那么问题来了有一个数a有一个数b我要让b等于a的第三位怎么算。
思路先让a右移俩位那么a原来的第三位现在就变成最后一位再让移后的数和1想与结果即为a原来的第三位。
一些面试常考的位操作运算
去掉最后一位 | (101101-10110) | x 1
在最后加一个0 | (101101-1011010) | x 1
在最后加一个1 | (101101-1011011) | x 11
把最后一位变成1 | (101100-101101) | x | 1
把最后一位变成0 | (101101-101100) | x | 1-1
最后一位取反 | (101101-101100) | x ^ 1
把右数第k位变成1 | (101001-101101,k3) | x | (1 (k-1))
把右数第k位变成0 | (101101-101001,k3) | x ~ (1 (k-1))
右数第k位取反 | (101001-101101,k3) | x ^ (1 (k-1))
取末三位 | (1101101-101) | x 7
取末k位 | (1101101-1101,k5) | x ((1 k)-1)
取右数第k位 | (1101101-1,k4) | x (k-1) 1
把末k位变成1 | (101001-101111,k4) | x | (1 k-1)
末k位取反 | (101001-100110,k4) | x ^ (1 k-1)
把右边连续的1变成0 | (100101111-100100000) | x (x1)
把右起第一个0变成1 | (100101111-100111111) | x | (x1)
把右边连续的0变成1 | (11011000-11011111) | x | (x-1)
取右边连续的1 | (100101111-1111) | (x ^ (x1)) 1
去掉右起第一个1的左边 | (100101000-1000) | x (x ^ (x-1))
判断奇数 (x1)1
判断偶数 (x1)0
取右边第一个1所在位置 x-x计算机原码、反码、补码
机器数
一个数在计算机中的表现形式叫做机器数这个数有正负之分在计算机中用一个数的最高位符号位用来表示它的正负其中0表示正数1表示负数。
例如正数7在计算机中用一个8位的二进制数来表示是00000111而负数-7则用10000111表示这里的00000111和10000111是机器数 真数
计算机中的机器数对应的真实的值就是真数对最高位符号位后面的二进制数转换成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]
有了原码为什么要使用反码和补码
因为人脑可以知道第一位是符号位可以根据符号位对真值的绝对值进行加减乘除但是对于计算机来说加减乘除是最最最基本的运算要设计的尽量简单计算机辨别符号位会让计算机的设计电路变得很复杂于是人们想出了让符号位也参与到运算上来。减去一个数等于加上他的负数。
使用原码参数运算的缺陷 从上面的原码表中可以看见左边每增加一个二进制单位对应的真数是递减的而右边每增加一个二进制单位对应的真数是递增的所以对于原码来说能满足正数的加法但无法满足负数的加法
21 [0000_0010]原[0000_0001]原[0000_0011]原 3
1±1[0000_00001]原[1000_0001]原[1000_0010]原-2
为了满足负数对加法的需求就必须让负数与他对应的二进制码是同步递增或者同步递减
于是就通过符号位不变其余位取反来满足这个同步递增或者递减的要求由于正数本来就满足它本身的加法所以不需要做任何改变。这就是反码的定义由来。 从上图的反码表中可以看到在运算不跨过0的时候正负数的加法已经能满足要求
-21[1111_1101]反[0000_0001]反[1111_1110]反-1
1271[1000_0000]反-127128 加法算出来是128由于128超过最大值余1所以取最小值开始的第一位也就是
最小值-127但是这里有个不合理的地方就是[1111_1111]和[0000_0000]都表示0这导致在实际计算中每当跨过0一次就有一个单位的误差
-12[1111_1110]反[0000_0010]反[0000_0000]反0
要解决这个问题就必须让反码中的[1111_1111]和[0000_0000]合并
由于[1111_1111][0000_0001][0000_0000],所以在负数反码的基础上1就可以解决反码中跨0的误差问题同时不会对负数与它对应的二进制反码的同步递增产生影响所以在反码的基础上1就完美的解决了符号参与预算的问题这就是补码为什么是在负数反码的基础上1的由来。 从上面的图中发现还有一个[1000_0000]的二进制没有对应任何真数于是就规定了这个数的真数是-128
所以补码的表示范围是[-128~127] 这样一来256个二进制正好表示256个整数在实际二进制的运算中超过范围其实就是对256的取余预算x128mod 256 - 128。