计算机二进制中的原码,反码,补码
公号:码农充电站pro
主页:https://codeshellme.github.io
文章目录
- 1,二进制数
- 2,二进制原码
- 3,数字溢出
- 4,二进制反码与补码
- 5,总结
计算机最基本的工作是处理数据,而数据的最底层表现形式是二进制,并非是我们人类熟悉的十进制。可以这么认为,计算机其实是很“笨的”,它只理解二进制数据。
今天,主要介绍计算机是怎样做加减运算的。你可能会想,加减运算?这么简单的事情,还用介绍?也许还真不是你想的那样。
计算机的运算是由CPU 完成的,而CPU 只会做加法运算,不会做减法运算,那计算机怎样完成减法工作呢?
1,二进制数
我们先来看看二进制数。
二进制数是由0,1 组成的,比如:
- 十进制的5,用二进制表示是 101。
- 十进制的7,用二进制表示是 111。
数字由正数和负数组成。为了表示正负数,计算机中就有了有符号数和无符号数之分:
- 无符号数:英文为
unsigned
,只能表示正数。 - 有符号数:英文为
signed
,即能表示正数,又能表示负数。
C/C++ 语言中的数字有有符号数和无符号数之分。
Java 语言所有的数字都是有符号数。
假如,我们用 4 位二进制,来表示无符号数,也就是只表示正数,能表示的范围是 0 到 15
,转换关系如下表:
十进制数 | 二进制数 | 十进制数 | 二进制数 |
---|---|---|---|
0 | 0000 | 8 | 1000 |
1 | 0001 | 9 | 1001 |
2 | 0010 | 10 | 1010 |
3 | 0011 | 11 | 1011 |
4 | 0100 | 12 | 1100 |
5 | 0101 | 13 | 1101 |
6 | 0110 | 14 | 1110 |
7 | 0111 | 15 | 1111 |
有符号数,即要表示正数,也要表示负数。
要用二进制表示有符号数,需要用二进制的最高位来表示符号,0
表示正
,1
表示负
。所谓的最高位,也就是最左边那一位。
用 4 位二进制,来表示有符号数,能表示的范围是 -8 到 7
,转换关系如下表:
十进制数 | 二进制数 | 十进制数 | 二进制数 |
---|---|---|---|
0 |
0 000
|
-8 |
1 000
|
1 |
0 001
|
-1 |
1 001
|
2 |
0 010
|
-2 |
1 010
|
3 |
0 011
|
-3 |
1 011
|
4 |
0 100
|
-4 |
1 100
|
5 |
0 101
|
-5 |
1 101
|
6 |
0 110
|
-6 |
1 110
|
7 |
0 111
|
-7 |
1 111
|
上表中的最高位的符号位,已标红。
要注意,对于有符号的4 位二进制 ----
1000
不是-0
,而是-8
。
可以总结出,对于N
位的二进制数:
- 无论是表示有符号数还是无符号数,都能表示
2^N
个数字。 - 若用于表示无符号数,则能表示的范围是
[0, 2^N - 1]
。 - 若用于表示有符号数,则能表示的范围是
[-2^(N-1), 2^(N-1) - 1]
。- 需要注意,在有符号数中,对于符号位是
1
,后面N-1
位全是0
,这种情况表示的是-2^(N-1)
(也就是所能表示的最小值),而不是-0
。 - 实际上是将
-0
这种情况解释成了最小值
,否则就会出现+0
和-0
两个0
。
- 需要注意,在有符号数中,对于符号位是
2,二进制原码
上面介绍到的二进制就是原码形式。
原码就是除符号位外的其他位,保存该二进制数的绝对值。
用原码进行加法计算
计算机中的数字运算都会先转成二进制数再进行计算。
我们用原码来计算加法,用4 位二进制数来计算 3 + 2
,过程如下:
可以看到,用原码计算加法是没有问题的。
用原码进行减法计算
我们再用原码来计算减法,因为CPU 只会计算加法,所以计算减法时,会将减法转换成加法。
比如,用4 位二进制数来计算计算 3 - 2
,会将其转换成 3 + (-2)
, 过程如下:
可以看到 3-2
计算出来的结果是 -5
,显然是错误的。
所以,用二进制原码来计算减法是行不通的。实际上,计算机计算减法用的是补码。
在介绍补码之前,我们先来看下什么是溢出。
3,数字溢出
计算机中数字的表示是需要内存空间的,不同类型的数字所能占用的空间是不一样的。
比如,在Java 语言中short
类型占用 2 个字节,int
类型占用 4 个字节。
一个字节等于 8 位。
既然空间大小是有限制的,所以计算机中的数字也是有范围的,即上限和下限,如果数字超出限制,就会产生溢出。超出上限叫上溢出,超出下限叫下溢出。而溢出的部分会直接被舍去。
就像我们在上文中介绍的,对于N
位二进制有符号整数,所能表示的范围是 [-2^(N-1), 2^(N-1) - 1]
。
由于溢出的部分会被舍去,那么最大值加1,将发生上溢出,变为最小值;最小值减1,将发生下溢出,变为最大值。
我们用Java 中的int
类型来验证,Java 中int
类型的最大、最小值分别是:
- 最大值:
Integer.MAX_VALUE
,是2147483647
。 - 最小值:
Integer.MIN_VALUE
,是-2147483648
。
用下面代码验证:
System.out.println(Integer.MAX_VALUE + 1 == Integer.MIN_VALUE); // true
System.out.println(Integer.MIN_VALUE - 1 == Integer.MAX_VALUE); // true
这两行代码的输出均为true
,说明最大值加1 变为最小值,最小值减1 变为最大值。
所以,在计算机中,只要一个整数的类型确定了,那么它所能占用的内存空间大小也就确定了,从而它所能表示的数字范围也就确定了。那么不管给这个整数加多大的数字,或者减多大的数字,最终的结果都只能在这个范围内旋转。
就像表盘一样,当表针走过最大值的时候,就变成了最小值。
同样,这也等同于数学中的取余运算。只要分母确定了,不管分子是多大,或者多小的数字,最终的结果也都是在一个确定的范围之内。
比如我们对十进制5
进行取余计算,那么最终的结果都是在[0, 4]
范围之内,如下:
0 % 5 = 0
2 % 5 = 2
397 % 5 = 2
99999 % 5 = 4
可以总结出,对数字N
进行取余,N >= 2
且为整数,那么结果都在 [0, N-1]
范围之内。
4,二进制反码与补码
知道了溢出,就可以介绍CPU 如何计算减法了。CPU 的减法运算使用了二进制补码,补码实际上就是采用了溢出的原理。
我们直接给出反码与补码的定义:
- 反码定义:正数的反码等于其原码,负数的反码是其原码除符号位外,按位取反。
- 补码定义:正数的补码等于其原码,负数的补码是其反码加1。
比如下面的几个数字:
十进制数 | 2 | 3 | -2 | -5 |
---|---|---|---|---|
二进制原码 | 0010 | 0011 |
1 010
|
1 101
|
二进制反码 | 0010 | 0011 |
1 101
|
1 010
|
二进制补码 | 0010 | 0011 |
1 110
|
1 011
|
我们用4
位二进制补码来计算 3+(-2)
,如下:
最高位的1
发生上溢出,直接被舍去,所以结果是正确的。
所以,要记住,真实的计算机中的二进制是用补码表示的,而不是原码。
5,总结
本篇文章主要介绍了:
- CPU 只能做加法,不能做减法,减法要转成加法做计算。
- 二进制数字有三种表示方式:
- 原码:除符号位外的其他位,保存该二进制数的绝对值。
- 反码:正数的反码等于其原码,负数的反码是其原码除符号位外,按位取反。
- 补码:正数的补码等于其原码,负数的补码是其反码加1。
- 计算机中的数字采用二进制补码表示,而不是原码表示。
- 补码采用了溢出的原理。
- 计算机中的数字是有范围限制的,超出限制会发生溢出。
- 超出上限叫做上溢出。最大值加1会发生上溢出,变为最小值。
- 超出下限叫做下溢出。最小值减1会发生下溢出,变为最大值。
(本节完。)
推荐阅读:
决策树算法-理论篇
决策树算法-实战篇
朴素贝叶斯分类-理论篇
设计模式之高质量代码
如何高效使用VIM
欢迎关注作者公众号,获取更多技术干货。
计算机二进制中的原码,反码,补码相关推荐
- 计算机中的原码,计算机中的原码反码补码移码
计算机中的原码反码补码移码 原码 数值 X 的原码记为 [X]原,如果机器字长为 n (即采用 n 个二进制位表示数据),则最高位是符号位,0 表示正号,1 表示负号,基余的 n~1 位表示数值的绝对 ...
- c语言中的原码反码补码,c语言中的原码 反码 补码
陈独秀的秘密 所谓原码就是前面所介绍的二进制定点表示法,即最高位为符号位,"0"表示正,"1"表示负,其余位表示数值的大小. 反码表示法规定:正数的反码与其原码 ...
- c语言原码 补码 反码,C语言 原码--反码--补码
//原码,反码,补码 #include #include //数值的表示方法--原码.反码和补码 //原码:最高位为符号位,其余各位为数值本身的绝对值 //反码: //正数:反码与原码相同 //负数: ...
- 关于计算机中 原码, 反码, 补码 详解
本篇文章讲解了计算机的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法计算原码的减法. 论证部分如有不对的地方请各位牛人帮忙指正! 希 ...
- python二进制反码例题_python中的进制转换和原码,反码,补码
python中的进制转换和原码,反码,补码 计算机文件大小单位 b = bit 位(比特) B = Byte 字节 1Byte = 8 bit #一个字节等于8位 可以简写成 1B = 8b 1KB ...
- 【程序员必修数学课】-基础思想篇-二进制-原码反码补码的数学论证
二进制计数法&原码&反码&补码 Ⅰ 前言 Ⅱ 二进制计数法 A. 什么是二进制计数法? B. 为什么要使用二进制? C. 二进制的位运算 D. 符号位 E. 溢出 Ⅲ 原码&a ...
- 二进制八进制十进制十六进制及原码反码补码
1.进制的介绍 定义:进位制,人们规定的一种进位方式:表示某一位置上的数,运算时是逢X进一位. 十进制是逢十进一:二进制是逢二进一,八进制是逢八进一: 常见进制:二进制,八进制,十进制,十六进制: 学 ...
- 计算机组成原理——基本组成 进制转化 奇偶校验 原码 反码 补码 移码 移位 原码补码乘法除法 IEEE754 加法器ALU
笔记来源于王道考研视频 第一章 通过电信号传递信息(低电平代表0,高电平代表1) 计算机系统 计算机系统=硬件+软件 软件 系统软件 应用软件 操作系统,数据库管理系统(DBMS),标准程序库(编程时 ...
- 大端 小端 原码 反码 补码 及内存中的表现
小端 和 大端 在内存中存储时,都是从内存的低地址往高地址存,即0x00000000 -> 0xffffffff 以汉字 "严"为例,Unicode码是4E25,需要两个字节 ...
- 【计算机组成原理】原码 反码 补码 移码的转换
原码 反码 补码 移码的转换 这三种机器码都是二进制数据的表现形式,可以表现正数和负数. 原码是可以直接表现出数据的正负和大小. 正数的原码.反码和补码都是相同的. 反码用于原码和补码的转换的功能. ...
最新文章
- .net中用css控制GridView样式
- 个推通知栏修改_浙大一院五一劳动节放假通知!手机办住院手续!还有这些攻略不能错过!...
- javascript 学习笔记之面向对象编程(二):继承多态
- Java遍历Map的4种方式
- 科一主观题刷题 0308
- Minigui3.0.12完美安装
- asp.net 两个控件放一行_思维导图?试试这两个宝藏网站吧
- 厉害了,蚂蚁金服!创造了中国自己的数据库 OceanBase
- epub 深入linux内核架构_深入分析Linux内核源代码6-Linux 内存管理(2)
- 每年都有人问“IT行业还能再火几年”,现实给出最好的答案
- Dart 基礎 - 3
- jQuery动画的实现
- 一个基于SpringBoot的在线教育系统「源码开源」
- 异星工厂0.16控制台代码
- 定义一个工资变量c语言,《工资管理》c语言程序设计.doc
- 360众测靶场云文件服务器,360 政企安全官网_帮助应对高级威胁攻击
- 计算机给文件重命名快捷键,计算机中文件重命名快捷键是什么
- html5经纬度定位 源码_利用HTML5定位功能获取经纬度,在根据经纬度利用百度地图获取位置信息...
- 关于netty的IllegalReferenceCountException refCnt: 0, decrement: 1
- 5月全球CTF比赛时间汇总来了!