计算机组成原理----原码,反码与补码

news2024/10/6 13:52:16

目录

1.原码的出现

2.反码的出现

3.补码的出现

4.关于补码


1.原码的出现

我们通常使用"+","-"判断数字的正负,而在计算机中,则将二进制的首位当作标记符号,"0"表示正数,"1"表示负数,这样就解决了在计算机中表示数值正负的问题,唯一的缺点就是第1位被占作符号位。

    0 0000001 原
 +  0 0000010 原
 =  0 0000011 原

2.反码的出现

原码解决了数值的正负表示问题,但是没有解决加减法的问题,由于计算机只会进行加法运算,所以对于3-5,我们可以转换为3+(-5)=-2,将其转换为加法运算,若用原码进行计算:

     0 0000011 原
 +   1 0000101 原
 =   1 0001000 原

得到十进制:-8,结果错误,看来直接用原码进行加法是不行的,因为原码的符号位参与了运算。

所以反码出现了:

① 正数的反码是本身

② 负数的反码是符号位不变,其余位取反

3的原码为: 0 0000011

-5的原码为:1 0000101

-5的反码为:1 1111010

用反码,计算一下:3 + (-5) = -2

     0 0000011 反
+    1 1111010 反
=    1 1111101 反

1 1111101是反码,需要转换为原码,就是除了符号位以外都取反,得到1 0000010

十进制:-2,结果正确! 我们发现反码解决了原码进行加法时错误的问题,并且符号位也参与了运算。可以实现计算机的加减运算。

补充:

其实原码进行加减也没有问题,只要排除符号位的干扰即可,我们可以这样做:

对于两个不同符号的数,我们先要比较两个数的绝对值大小,然后用绝对值大的数减去绝对值效地数,然后为结果选择合适的符号位。

3.补码的出现

当我们遇到如下情况时:

正数+1的原码为:0 0000001

负数-1的原码为: 1 0000001

用反码,计算一下:1 + (-1) = 0

     0 0000001 反
 +   1 1111110 反
 =   1 1111111 反

得到结果:1 1111111,因为1 1111111的首位为1,表示为负数,反码需要转化为原码

把1 1111111除符号位取反得原码:1 0000000

得到十进制:-0,0本来是没有正负之分的,所以我们发现用反码计算,真值的部分是正确的,问题出现在符号位。所以出现了补码:

当我们对数值做如下变换:

① 正数的补码就是其本身

② 负数的补码就是本身取反再+1,也就是反码+1

再计算一下上面的问题:

正数+1的补码为:0 0000001

负数-1的补码为: 1 1111111

     0 0000001 补
 +   1 1111111 补
 =   0 0000000 补

得 1 0 0000000 高位舍去

得到结果:0 0000000

结果的首位为0,表示为正数,不需要再取反,则原码就为:0 0000000

看到这里,我们可以总结一下了:

1.补码能够正确地进行加减法运算,所以计算机的加减运算都是通过补码实现的。

原码的特点:

1.原码加减运算比较复杂

2.原码有正零和负零两种表示方式,[+0]原=0 0000000 [-0]原=1 0000000

反码的特点:

1.正数的反码就是它本身,负数的反码就是符号位不变,其余位取反

2.对应原码,反码的0也有两种表示方式,[+0]反=0 0000000 [-0]反=1 1111111

对于8位二进制数(含符号位)而言,其原码和反码能表示的范围相同,都是-127~127

原码:1 111 1111 (-127)到 0 111 1111(+127)

反码:1 000 0000 (-127)到 0 000 0000(+127)

补码的特点这里只说一点,后面再补充:

补码的0只有一种表示形式,就是0 0000000,我们将反码+1得到补码:

[+0]补=0 0000000

[-0]补=1 0 0000000,超过二进制位数,舍去最高位,得到0 0000000

所以补码的"0"只有1种表示方式:0 0000000

4.关于补码

我们来看最后一种特殊情况:

用补码,计算一下:-1 + (-127) = -128

    1 1111111 补
+   1 0000001 补
=   1 0000000 补

得到结果:1 0000000

因为1 0000000的首位为1,表示为负数,补码需要转化为原码, 把1 0000000减1, 得到 0 1111111,再符号位不变,其余取反:0 0000000, 得到十进制:0,结果错误,问题出在哪里?还记得我们上面总结的原码的表示范围吗:-127~127,-128在8位二进制补码中没有对应的原码,他是只存在于补码系统中的特殊的数,即,在补码中,1 0000000表示-128

所以,对于8位二进制补码,其范围是-128~127

这也可以解释为什么1+127为-128:

因为得到的数值超过了计算机能表示的数值范围,上面这种情况叫做上溢,下溢则对应下面这种情况:

可以观察到:补码的表示就像一个循环,结果超过了上界,就循环到负数的位置了,超过下界,就循环到正数的位置了。像一个钟表一样,过了24点,就是1点,可以想象一下。

无符号数和有符号数的表示:

无符号数128:10000000

有符号数-128:10000000

计算机存储这两个数时,表示是一样的,那计算机是如何区分这2个数的呢?

其实计算机在存储数据时候,并不会在意这个数是正数(首位是0)还是负数(首位是1),它只负责存储数据,至于这个数据代表的含义,它不关心

对于这个数据的解释,也是根据我们的需要来实施的:

如果你把它当做是有符号数,那么10000000就是代表-128

如果你把它当做是无符号数,那么10000000就是代表128

我们会分情况确定这个数是表示正数还是负数。这就是我们在学习C语言时候,区分有符号和无符号的原因。又例如在计算机存储的是1 0001011

1 0001011,假如你把它当作无符号数,那首位就表示数值,值为139

1 0001011,假如你把它当作有符号数,那首位就表示符号位,值为-117

我们拿这两个数进行运算,只要我们自己清楚首位是不是符号位,符号位也可以参加运算,得出的结果是没问题的。

在对比128和-128的时候,会出现这2个数相等的情况吗?

不会,有符号数与无符号数比较时,有符号数会转换成无符号数来进行比较

8位无符号的128是:10000000

8为有符号的-128是:10000000,但转为8位无符号是:00000000

此时依然1000000 > 00000000

对于无符号数:
原码形式:

0000 0000 - 0111 1111            0 ~ 127(原码)
1000 0000 - 1111 1111          128 ~ 255(原码)

补码形式:

0000 0000 - 0111 1111            0 ~ 127(补码)
1000 0000 - 1111 1111          128 ~ 255(补码)

对于有符号数:

1 111 1111 - 0 111 1111        -127~127(原码)

1 000 0000 - 0 111 1111       -128~127(补码)

这里不再讲反码了,因为反码的主要作用是实现原码和补码的转换

可以总结总结补码了:

1.计算机所有的存储和计算都是通过补码的形式实现的。

2.正数补码是他本身,负数补码是其取反+1(或者说反码+1)。

3.补码中"0"表示的方式只有1种,那就是0 0000000,我们也可以发现,8位2进制数2^8=256位,每一位都有含义,原码范围-127~127,有255位数,别忘了原码中有[+0]和[-0],所以总共256位数,对于补码-128~127,总共256位数。

4.补码解决了符号位不能参与运算的问题。在用反码计算时,真值的部分是正确的,问题就出现在符号位

5.补码中有"-128",他是一个特殊的数,没有对应的原码。


有错误请佬们指出💖💖💖,后续深入学习会继续补充,别忘了收藏起来~~

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

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

相关文章

剖析【C++】——类与对象(中)——小白篇—超详解

目录 1.类的6个默认成员函数: 1. 默认构造函数(Default Constructor) 2. 析构函数(Destructor) 3. 拷贝构造函数(Copy Constructor) 4. 拷贝赋值运算符(Copy Assignment Operato…

【Mybatis】映射文件中#{}里的其他属性

#{}里除了可以写接收参数的名称外,还可以设置javaType,jdbcType,mode,numericScale,resultMap,typeHandler,jdbcTypeName这些属性的。 其他的属性除mode(存储过程相关讲到存储过程的时候在讲)外使用方式都…

单链表的相关题目

1.删除链表中给定值val的所有结点 public void removeall(int key) {//由于是删除链表中所有和key值相同的结点,所以可以设置两个ListNode类型的数据,一个在前面,一个在后面.//直到前面的走到链表的最后,这样完成了遍历.//先判断一下这个链表是否为空if(headnull){System.out.…

Vim安装与配置教程(解决软件包Vim没有安装可候选)

一、Vim检测是否安装 1-输入vi查看是否安装; 2-按Tab键,显示以下字符为未安装; 3-显示以下字符为已安装(可以看到有Vim) 二、Vim安装过程 1. 打开终端,输入 sudo apt install vim; 2. 输入Y/y&#xff…

STM32Cube系列教程11:使用STM32 RNG硬件随机数模块生成彩票号码

文章目录 配置RNG模块编写代码获取生成的随机数运行测试 今天写段代码测试一下STM32U083RC的(RNG)硬件随机数模块 顺便写个小demo生成7位真随机数的彩票号码,帮助那些买彩票还有选择困难症的人群 (doge)(手动狗头)。 全部代码以上传到github:https://gi…

C++ (week5):Linux系统编程3:线程

文章目录 三、线程1.线程的基本概念①线程相关概念②我的理解 2.线程的基本操作 (API)(1)获取线程的标识:pthread_self(2)创建线程:pthread_create()(3)终止线程①pthread_exit():当前线程终止,子线程主动退出②pthread_cancel()&…

C语言 | Leetcode C语言题解之第118题杨辉三角

题目&#xff1a; 题解&#xff1a; int** generate(int numRows, int* returnSize, int** returnColumnSizes) {int** ret malloc(sizeof(int*) * numRows);*returnSize numRows;*returnColumnSizes malloc(sizeof(int) * numRows);for (int i 0; i < numRows; i) {re…

【RocketMQ】安装RocketMQ5.2.0(单机版)

下载 官网下载地址&#xff1a;下载 | RocketMQ github地址&#xff1a;Tags apache/rocketmq GitHub 选择对应的版本下载。https://dist.apache.org/repos/dist/release/rocketmq/5.2.0/rocketmq-all-5.2.0-bin-release.zip 5.2.0的二进制包&#xff1a;下载地址 5.2.0的…

C语言 | Leetcode C语言题解之第117题填充每个节点的下一个右侧节点指针II

题目&#xff1a; 题解&#xff1a; void handle(struct Node **last, struct Node **p, struct Node **nextStart) {if (*last) {(*last)->next *p;}if (!(*nextStart)) {*nextStart *p;}*last *p; }struct Node *connect(struct Node *root) {if (!root) {return NULL…

随机森林算法实现分类

随机森林算法实现对编码后二进制数据的识别 1.直接先上代码&#xff01; import numpy as np import pandas as pd from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import …

数据结构之堆(优先级队列)

前言 在上一章我们讲了二叉树&#xff0c;这一节我们来讲堆&#xff08;优先级队列&#xff09;&#xff0c;所以想知道堆创建&#xff0c;可以看一下二叉树的一些简单概念。http://t.csdnimg.cn/4jUR6http://t.csdnimg.cn/4jUR6 目录 前言 堆 1.概念 2.优先级队列的模拟实…

Day06-Mybatis

1. Mybatis介绍 2. Mybatis连接数据库并返回数据事例 连接oracle数据的设置方式 spring.application.namespringboot-mybatis spring.datasource.driver-class-nameoracle.jdbc.OracleDriver spring.datasource.urljdbc:oracle:thin:192.168.100.66:1521:orcl spring.datasour…

每日一题《leetcode--59.螺旋矩阵 》

https://leetcode.cn/problems/spiral-matrix-ii/ 这道题跟我昨天发布的那道题一模一样&#xff0c;只需要注意这个矩阵是n*n。 文章代码如下&#xff1a; int** generateMatrix(int n, int* returnSize, int** returnColumnSizes) {int** array (int**)malloc(sizeof(int*) *…

Python | Leetcode Python题解之第118题杨辉三角

题目&#xff1a; 题解&#xff1a; class Solution:def generate(self, numRows: int) -> List[List[int]]:ret list()for i in range(numRows):row list()for j in range(0, i 1):if j 0 or j i:row.append(1)else:row.append(ret[i - 1][j] ret[i - 1][j - 1])ret…

HCIP-Datacom-ARST自选题库__BGP多选【22道题】

1.BGP认证可以防止非法路由器与BGP路由器建立邻居&#xff0c;BGP认证可以分为MD5认证和Keychain认证&#xff0c;请问以下哪些BGP报文会携带BCGP Keychain认证信息?(报头携带) open Update Notication Keepalive 2.传统的BGP-4只能管理IPv4单播路由信息&#xff0c;MP-B…

总线带宽(总线系统的数据传送速率)

定义 总线上每秒钟传输的最大字节数或比特数 表示方法 通常使用“比特率”来表示&#xff0c;单位为比特每秒&#xff08;bps&#xff0c;b/s&#xff09;。 计算公式 总线带宽总线宽度/传输周期 其中&#xff0c;总线宽度是指数据总线的位数&#xff08;单位&#xff1a…

GBB和Prob IoU[旋转目标检测理论篇]

在开始介绍YOLOv8_obb网络之前,需要先介绍一下arxiv.org/pdf/2106.06072 这篇文章的工作,因为v8_obb就是基于这篇论文提出的GBB和prob IoU来实现旋转目标检测的。 1.高斯分布 一维高斯分布的规律是中间高两边低,且当x为均值的时候取到最大值,表达式如下,标准正态分布图如…

数据库(10)——图形化界面工具DataGrip

以后关于数据库的图片演示就使用DataGrip了 : ) 创建数据库和表 在连接上数据库之后&#xff0c;可以选择Schema创建一个新的数据库。 点击OK后&#xff0c;就已经创建了一个空的表。 要在数据库中建立一张新的表&#xff0c;右键数据库&#xff0c;点击new table 要给新表添…

基于开源项目HAL STM32F4 +DSP库跑SVPWM开环速度测试

HAL STM32F4 ARM DSP库跑SVPWM开环速度测试 ✨本篇硬件电路和代码来源于此开源项目&#xff1a;https://github.com/MengYang-x/STM3F401-FOC/tree/main&#x1f4cd;硬件电路和项目介绍&#xff0c;立创开源广场&#xff1a;https://oshwhub.com/shadow27/tai-yang-neng-wu-re…

STL库--string

目录 string的定义 string中内存的访问 string常用函数实例解析 string的定义 定义string的方式跟基本类型相同&#xff0c;只需要在string后跟上变量名即可&#xff1a; string str; 如果要初始化&#xff0c;可以直接给string类型的变量进行赋值&#xff1a; string s…