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

参考:运算符的计算(按位与 按位或 异或 取反)
作者:一只青木呀
发布时间: 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_medium=distribute.pc_relevant_t0.none-task-blog-searchFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-searchFromBaidu-1.control

目录

  • 位运算
    • 按位与运算符 [ & ]
    • 按位或运算符 [ | ]
    • 异或运算符 [ ^ ]
    • 取反运算符 [ ~ ]
    • 移位操作
    • 一些面试常考的位操作运算
  • 计算机原码、反码、补码
    • 机器数
    • 真数
    • 原码
    • 反码
    • 补码
    • 有了原码为什么要使用反码和补码

位运算

按位与运算符 [ & ]

运算规则:依次比较两个二进制数的每一位,全部为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

计算机原码、反码、补码

机器数

一个数在计算机中的表现形式叫做机器数,这个数有正负之分,在计算机中用一个数的最高位(符号位)用来表示它的正负,其中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]

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

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

使用原码参数运算的缺陷
在这里插入图片描述
从上面的原码表中可以看见左边每增加一个二进制单位对应的真数是递减的,而右边每增加一个二进制单位对应的真数是递增的,所以对于原码来说,能满足正数的加法,但无法满足负数的加法

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

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

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

于是就通过符号位不变,其余位取反来满足这个同步递增或者递减的要求,由于正数本来就满足它本身的加法,所以不需要做任何改变。这就是反码的定义由来。
在这里插入图片描述
从上图的反码表中可以看到在运算不跨过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的由来。
在这里插入图片描述
从上面的图中发现还有一个[1000_0000]的二进制没有对应任何真数,于是就规定了这个数的真数是-128

所以补码的表示范围是[-128~127] ,这样一来256个二进制正好表示256个整数,在实际二进制的运算中超过范围其实就是对256的取余预算(x+128)mod 256 - 128。

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

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

相关文章

Docker03 Docker基础知识、Docker实战

1 Docker基础知识 1.1 什么是Docker Docker是一个可以装应用的容器&#xff0c;就像杯子可以装水、书包可以装书一样&#xff1b;docker官网 Docker是Docker公司开发的&#xff0c;并开源到GitHub上; Docker是跨平台的&#xff0c;支持windows、linux、Macos 1.2 Docker思想 1.…

Java字符串简化_关于java查询语句 如何简化的问题

首先&#xff0c;请你告诉我你使用PreparedStatement的理由&#xff0c;为什么不使用Statement&#xff1f;二者有什么区别&#xff1f;然后 你用到了PreparedStatement的特性了吗&#xff1f;接下来我们在探讨这代码该怎么写。下面的代码仅供参考&#xff0c;基本不具有实践意…

phpcms_v9推送到其他栏目后再在其他栏目删除导致数据库出错

修改phpcms/model/content_model.class.php大概454行的update_category_items()函数private function update_category_items($catid,$action add,$cache 0) {$this->category_db pc_base::load_model(category_model);if($actionadd) {$this->category_db->update…

Linux网络编程小知识(字节序、IP格式、函数、子网掩码、DNS域名解析代码实现)

参考&#xff1a;网络编程前的一些小知识–Linux笔记 作者&#xff1a;一只青木呀 发布时间&#xff1a; 2021-04-12 23:19:10 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/115560197 参考&#xff1a;DNS域名解析 作者&#xff1a;一只青木呀 发布…

java ndk 在哪_NDK简介

一、NDK简介&#xff1a;C/C的动态库。Dalvik通过JNI编程方式调用C/C代码。NDK编程提高软件性能&#xff0c;加密保护APK文件ndk-build NDK编译生成脚本Java编译时会根据java声明文件生成dex文件&#xff0c;即使没有java代码NDK共享库&#xff1a;NDK生成的 .so文件(类…

ARM汇编基础详解(PS学习汇编的原因)

目录前言1.GNU 汇编语法2.Cortex-A7 常用汇编指令2.1 处理器内部数据传输指令&#xff08;内部寄存器数据非内存数据&#xff09;2.2 存储器访问指令&#xff08;RAM&#xff09;2.3 压栈和出栈指令&#xff08;了解&#xff09;2.4 跳转指令2.5 算术运算指令2.6 逻辑运算指令前…

java formatter()_Java Formatter locale()用法及代码示例

locale()方法是java.util.Formatter的内置方法&#xff0c;该方法返回语言环境。此区域设置由格式化程序构造设置。具有语言环境参数的该对象的format方法不会更改此值。用法&#xff1a;public Locale locale()参数&#xff1a;该函数不接受任何参数。返回值&#xff1a;如果未…

linux中tree命令

需要安装tree包(安装&#xff1a;yum -y install tree)。 tree命令的选项说明如下&#xff1a; 【 匹配选项&#xff1a;】 -L&#xff1a;用于指定递归显示的深度&#xff0c;指定的深度必须是大于0的整数。 -P&#xff1a;用于显示统配符匹配模式的目录和文件&#xff0c;但是…

查看LINUX进程内存占用情况

可以直接使用top命令后&#xff0c;查看%MEM的内容。可以选择按进程查看或者按用户查看&#xff0c;如想查看oracle用户的进程内存使用情况的话可以使用如下的命令&#xff1a; (1)top top命令是Linux下常用的性能分析工具&#xff0c;能够实时显示系统中各个进程的资源占用状况…

ARM(IMX6U)裸机汇编LED驱动实验——驱动编写、编译链接起始地址、烧写bin文件到SD卡中并运行

参考&#xff1a;Linux之ARM&#xff08;IMX6U&#xff09;裸机汇编LED驱动实验–驱动编写 作者&#xff1a;一只青木呀 发布时间&#xff1a; 2020-08-07 09:13:48 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/107851318 参考&#xff1a;Linux之…

Tools: geos 使用指南

1. 下载geos 2. 进入VS开发人员命令提示3、依次执行如下命令 >VCVARS32.BAT>cd D:\DevTool\geos-3.7.0>atuogen.bat>nmake /f makefile.vc> 编译成功后&#xff0c;会在D:\DevTool\geos-3.7.0\src目录下生成geos.lib, geos_i.lib, geos_c_i.lib, geos.dll, geos…

java 面试 概率论_编程培训-115个Java面试题和答案B.pdf

编程培训-115个Java面试题和答案B.pdf “玩转”Java系列 1 题目115个Java面试题和答案终极(下) 第一篇讨论了面向对象编程和它的特点&#xff0c;关于Java和它的功能的常见问题&#xff0c;Java的集合类&#xff0c; 垃圾收集器&#xff0c;本章主要讨论异常处理&#xff0c;Ja…

An Introduction to Our Code Breaking Team

小朋友们大家好&#xff0c;知道我们是谁吗&#xff1f;对了&#xff0c;我们就是Team Code Breaking&#xff01; 关于这个队名&#xff0c;我们讨论了很久&#xff0c;这个Code Breaking似乎是来源于某部电影&#xff0c;又似乎是来源于某本小说&#xff0c;或许单纯地只是觉…

ARM(IMX6U)裸机之I.MX6ULL硬件启动方式的选择

参考&#xff1a;Linux之ARM&#xff08;IMX6U&#xff09;裸机之I.MX6ULL启动方式详解 作者&#xff1a;一只青木呀 发布时间&#xff1a; 2020-08-09 16:32:07 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/107891591 目录启动方式的选择①.串行下…

python 操作mongo

1.  导包&#xff1a; import pymongo 2.  建立连接 client pymongo.MongoClient("127.0.0.1",27017) 3.  获取数据库 db client["test1"] 4.  获取集合 col db["t2"] 5.  插入数据&#xff1a; col.insert_one({ name:aa , age:2 …

java 混码_kotlin java 混合代码 maven 打包实现

kotlin简介kotlin是一种针对java 平台的新编程语言。kotlin简洁、安全、务实&#xff0c;并且专注于与java代码的互操作性。它几乎可以用在现在java使用的任何地方&#xff1a;服务端开发、android应用等等。kotlin 可以很好地和所有现存的java库和框架一起工作&#xff0c;而且…

w3 protocol

http://www.w3.org/Protocols/HTTP/HTRQ_Headers.html http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

ARM(IMX6U)裸机之I.MX6ULL启动头文件详解(内部BOOT ROM、IVT + Boot data + DCD + led.bin)

参考&#xff1a;Linux之ARM&#xff08;IMX6U&#xff09;裸机之I.MX6ULL镜像烧写以及启动头文件的详解 作者&#xff1a;一只青木呀 发布时间&#xff1a; 2020-08-09 17:10:00 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/107895975 目录BOOT R…

oracle日期函数

ORACLE日期函数大全&#xff01;2009-03-12 14:16:10日期函数 Oracle PL/SQL Oracle的日期函数相信很多人都有过统计某些数据的经历&#xff0c;比如&#xff0c;要统计财务的情况&#xff0c;可能要按每年&#xff0c;每季度&#xff0c;每月&#xff0c;甚至每个星期来分别统…

(转)git遇到的问题之“Please make sure you have the correct access rights and the repository exists.”...

对于git的提交一直很小心翼翼&#xff0c;感觉一不小心就会踩到莫名的坑。 这不&#xff0c; 某天commit 就遇到了On branch master nothing to commit (working directory clean) 一查意思。你的分支很干净&#xff1f; 干净&#xff1f;excuse me&#xff1f; 然后git push …