关于计算机中 原码,反码,补码的简单整理

概念:

简述:

Everybody Kown,计算机历史上有两位很重要的人物,第一位是计算机科学奠基人(Alan Mathison Turing) 阿伦·图灵 ,他在计算机科学方面的贡献主要有两个,一是建立图灵机(Turing Machine,TM)模型,奠定了可计算理论的基础;二是提出了图灵测试(Turing Test),阐述了机器智能的概念……(计算机里面最高的奖项就是图灵奖,每年颁发给在计算机科学领域做出杰出贡献的人才,被誉为计算机业界和学术界的诺贝尔奖),

第二位则是被称为现代计算机之父的美籍匈牙利数学家(Von Neumann) 冯·诺依曼,他的主要贡献是1945年,冯·诺依曼在指定EDVAC(电子离散变量计算机)的计划中(公认的第一台计算机),提出了存储程序的概念,就是将程序和数据一起存放在存储器中,以后凡是以此概念为基础的各类计算机,都被称为冯·诺依曼计算机,它的特点主要包括了:

  1. 计算机有运算器,存储器,控制器和输入设备,输出设备五大部件组成
  2. 指令和数据以同等地位存于存储器中,并可按地址寻访
  3. 指定和数据均用二进制代码表示
  4. 指令由操作码和地址码组成,操作码用来表示操作的性质,地址码用来表示操作数在存储器中的位置
  5. 指令在存储器内按顺序存放,通常,指令是顺序执行的,在特定的条件下,可以根运算结果或根据设定的条件改变执行顺序
  6. 机器以运算器为中心,输入输出设备与存储器键的数据传送通过运算器完成。

其中运算器,只有加法运算器,没有减法运算器

  1. 减法和加法是一样的,只要加个电信号,把减数变成负的就可以了,把加变成减,看看加法器的电路图,一般“加法器”同时是“减法器”。
  2. 乘法器和除法器:乘法器很简单,用加法器多加几次,或者增加硬件,多弄几个加法器就可以了,乘数、被乘数都要先转化为二进制,二进制的乘法远比十进制简单,比如乘数是1011,只需将将被乘数分别左移3位、1位,移动后补入0,并将这三个数(被乘数左移3位的、被乘数左移1位的及未移位的被乘数)在累加器中相加,所得总和就是积,根据需要积可再转化为十进制。
    除法与乘法类似,除法就是乘法的逆运算,只不过将左移改为右移,加改成减。实际上减也是通过取补码后再加,因此计算机芯片上的累加器是最繁忙的部分。运算比较复杂,大概就是这么回事。
  3. 乘法运算使用加法和移位操作实现的,根据机器数的不同,又分为原码乘法和补码乘法,具体的细节记不太得了……就不一一赘述了。(这个是涉及到位运算,一般在开发中很少使用位运算的,具体怎么运算的是computer的cpu完成的,复杂且繁琐,如果特别感兴趣,《计算机组成原理》中有详细的介绍……)
  4. 除法运算可用加(减)和移位操作实现的,根据机器数的不同,又分为原码除法和补码除法,具体的细节记不太得了……就不一一赘述了。(这个是涉及到位运算,一般在开发中很少使用位运算的,具体怎么运算的是computer的cpu完成的,复杂且繁琐,如果特别感兴趣,《计算机组成原理》中有详细的介绍……)

 

  1. Notice:计算机硬件结构中,也不全是“只有一个加法器”,至少还有“浮点运算的加法单元和浮点乘法,浮点除法的单元”.

       所以,计算机中没法直接做减法运算的,它的减法运算都是通过加法运算来实现的

比如,10 - 3 = 7 ,这很简单,在计算机中,它会加上减数的相反数得到的是一样的结果: 那么就是 10 + -3 = 7;所以这时候就要有负数的概念,那么这就是为什么不得不引入一个符号位来表示正数,和负数了,(最高位是符号位,“0” 表示正数,“1”表示负数)

原码:

原码就是指的二进制定点表示法,每个十进制数字都有它对应的二进制码,即最高位是符号位,“0” 表示正数,“1”表示负数,其他的位数存放该数的二进制的绝对值,也就是表示该数值的大小。

如下图所示,给出部分数字的二进制原码;

 

比如:

先加正数(这很简单):

3 + 3 = 6 ;换成二进制就是:(这没问题)

  3       +      3    = 6

0000 0011 + 0000 0011 = 0000 0110 

0 + 0 = -0;换成二进制就是:(这也没问题,0 和 -0 本身就是同一个数字)

    0     +     -0     = -0

0000 0000 + 1000 0000 = 1000 0000

但如果是一个正数加它的相反数:比如:

3 + -3 = ? ; 换成二进制就是:

   3      +    -3     = -6 

0000 0011 + 1000 0011 = 1000 0110 

3 + -3 = -6? why?

原因很简单: 就是表示正负数的符号位所引起的

不光只是一个正数加它的相反数使用原码运算会这样,负数和负数使用原码运算也是会出现莫名其妙的效果的;

比如:

  -3      +     -3    = 6 

1000 0011 + 1000 0011 = 1(丢弃最高位1) 0000 0110 (由于一个字节规定了只能是八个位所以最高位丢弃不要,硬件决定了)

由此可以看出,如果是正数之间的运算使用原码进行运算,完全没有任何的问题,因为这本身就是一个很简单的二进制加法,但是正数和负数,负数和负数的运算就有问题了;

于是,引入了反码:
 


反码:

正数的反码与原码相同而负数的反码,是对其原码逐位取反,符号位不变(所谓取反就是 1 变 0 , 0 变 1)

如下图所示,给出部分负数数字的二进制反码;

从光是从原码的运算就不难看出,原码最大的问题就在于任意一个正数加上它的相反数不等于 0 ;

紧接着: 试试用正数的原码加上它的相反数的反码?

比如:

3 + -3 = ?

  3       +   -3(反码) = -0(就是0本身)
0000 0011 + 1111 1100  = 1111 1111

3 + -3 = 0;

 

正数 + 负数?

 7(原码) + -2(反码) = -5(反码)
0000 0111 + 1111 0010  = 1111 0101

再比如:

 -4(原码)+ -4(反码)= 6(原码)?
1000 1011 + 1111 1011 = 1(丢弃最高位)0000 0110 (由于一个字节规定了只能是八个位所以最高位丢弃不要,硬件决定了)

负数相加?why?

-1(原码) + -5(反码)= -7(反码)?
1000 0001 + 1111 1010 = 1111 1000 

发现明显不对:

反码的出现的好处就是解决了正数加它的相反数等于0  和正数加负数的运算的结果是正确,而负数和负数相加的结果始终都是错的,这始终不是还不是完美的解决方案;

于是补充了补码:


补码:

正数的补码与其原码相同(换言之就是正数的原、反、补都是一样的);负数的补码是在反码的末位 + 1;(负数的补码是它的原码自低位向高位,尾数的第一个  “1” 及其右边的 “0” 保持不变,左边的各位按位取反,符号位不变,0除外!0则全部取反,0比较特殊,介于正数与负数之间,它的原、反、补都是 0000 0000 ,它严格意义上来说属于正数!)

如图所示:

现在再来试验

正数与负数相加,

比如:

  3(补码)+  -6(补码)= -3 (补码)    
0000 0011 + 1111 1010 = 1111 1101

 

 -2(补码)+  7(补码) = 5(补码) 
1111 1110 + 0000 0111 = 1(丢弃最高位1)0000 0101(由于一个字节规定了只能是八个位所以最高位丢弃不要,硬件决定了)

正数与它的相反数相加

 9(补码) +  -9(补码)= 0(补码)
0000 1001 + 1111 0111 = 1(丢弃最高位1) 0000 0000(由于一个字节规定了只能是八个位所以最高位丢弃不要,硬件决定了)
 6(补码) + -6(补码) = 0(补码)
0000 0110 + 1111 1010 = 1(丢弃最高位1)0000 0000(由于一个字节规定了只能是八个位所以最高位丢弃不要,硬件决定了)
  0(补码)+  -0(补码) = 0(补码)
0000 0000 + 0000 0000 = 0000 0000

Notice:从科学的角度来说 0 和 -0 就是同一个数, 0这个数比较特别,介于正数和负数之间,它的绝对值就是它本身,它并没有相反数!

 

负数与负数相加:

  -4(补码)+ -5(补码) = -9(补码)
1111 1100 + 1111 1011 = 1111 0111 
 -2(补码)+ -6(补码) = -8(补码) 
1111 1110 + 1111 1010 = 1111 1000
-8(补码) + -9(补码) = -17(补码)
1111 1000 + 1111 0111 = 1110 1111
-7(补码)  + -3(补码) = -10(补码)
1111 1001 + 1111 1101 = 1111 0110

 

OK,Perfect ,运算全部正确!

 

由此可见!计算机中的运算都是按照补码的形式进行运算的!

 

平时使用的计算器,它的负数都是已经以补码的形式转好了的,

由于正数的原码,反码,补码都是一样的,所以看到的始终都是一样的二进制码!

不难看出,计算机科学家们引入了原码、反码、补码的就是为了解决做减法的问题,加减乘除四则运算甚至更复杂的运算得到很完美的解决方案!存在即合理,尤其是这种发明的,定死的,千万不要纠结为什么要有反码?,为什么要有补码?我猜之所以这样,设计理念,设计思想均来源于生活,只能说二级制和十进制的运算机制不一样……,它没有加减乘除法口诀表…… 加法,减法是相对的,乘法,除法是相对的……,就好比正数, 负数是相对的一样

 

简单整理了一下,谢观……

热门文章

暂无图片
编程学习 ·

exe4j详细使用教程(附下载安装链接)

一、exe4j介绍 ​ exe4j是一个帮助你集成Java应用程序到Windows操作环境的java可执行文件生成工具,无论这些应用是用于服务器,还是图形用户界面(GUI)或命令行的应用程序。如果你想在任务管理器中及Windows XP分组的用户友好任务栏…
暂无图片
编程学习 ·

AUTOSAR从入门到精通100讲(126)-浅谈车载充电系统通信方案

01 引言 本文深入研究车载充电系统策略,设计出一套基于电动汽车电池管理系统与车载充电机的CAN通信协议,可供电动汽车设计人员参考借鉴。 02 电动汽车充电系统通讯网络 电动汽车整车控制系统中采用的是CAN总线通信方式,由一个整车内部高速CAN网络、内部低速CAN网络和一个充电…
暂无图片
编程学习 ·

CMake(九):生成器表达式

当运行CMake时,开发人员倾向于认为它是一个简单的步骤,需要读取项目的CMakeLists.txt文件,并生成相关的特定于生成器的项目文件集(例如Visual Studio解决方案和项目文件,Xcode项目,Unix Makefiles或Ninja输入文件)。然…
暂无图片
编程学习 ·

47.第十章 网络协议和管理配置 -- 网络配置(八)

4.3.3 route 命令 路由表管理命令 路由表主要构成: Destination: 目标网络ID,表示可以到达的目标网络ID,0.0.0.0/0 表示所有未知网络,又称为默认路由,优先级最低Genmask:目标网络对应的netmaskIface: 到达对应网络,应该从当前主机哪个网卡发送出来Gateway: 到达非直连的网络,…
暂无图片
编程学习 ·

元宇宙技术基础

请看图: 1、通过AR、VR等交互技术提升游戏的沉浸感 回顾游戏的发展历程,沉浸感的提升一直是技术突破的主要方向。从《愤怒的小鸟》到CSGO,游戏建模方式从2D到3D的提升使游戏中的物体呈现立体感。玩家在游戏中可以只有切换视角,进而提升沉浸…
暂无图片
编程学习 ·

flink的伪分布式搭建

一 flink的伪分布式搭建 1.1 执行架构图 1.Flink程序需要提交给 Job Client2.Job Client将作业提交给 Job Manager3.Job Manager负责协调资源分配和作业执行。 资源分配完成后,任务将提交给相应的 Task Manage。4.Task Manager启动一个线程以开始执行。Task Manage…
暂无图片
编程学习 ·

十进制正整数与二进制字符串的转换(C++)

Function one: //十进制数字转成二进制字符串 string Binary(int x) {string s "";while(x){if(x % 2 0) s 0 s;else s 1 s;x / 2;}return s; } Function two: //二进制字符串变为十进制数字 int Decimal(string s) {int num 0, …
暂无图片
编程学习 ·

[含lw+源码等]微信小程序校园辩论管理平台+后台管理系统[包运行成功]Java毕业设计计算机毕设

项目功能简介: 《微信小程序校园辩论管理平台后台管理系统》该项目含有源码、论文等资料、配套开发软件、软件安装教程、项目发布教程等 本系统包含微信小程序做的辩论管理前台和Java做的后台管理系统: 微信小程序——辩论管理前台涉及技术:WXML 和 WXS…
暂无图片
编程学习 ·

树莓派驱动DHT11温湿度传感器

1,直接使用python库 代码如下 import RPi.GPIO as GPIO import dht11 import time import datetimeGPIO.setwarnings(True) GPIO.setmode(GPIO.BCM)instance dht11.DHT11(pin14)try:while True:result instance.read()if result.is_valid():print(ok)print(&quo…
暂无图片
编程学习 ·

ELK简介

ELK简介 ELK是三个开源软件的缩写,Elasticsearch、Logstash、Kibana。它们都是开源软件。不过现在还新增了一个 Beats,它是一个轻量级的日志收集处理工具(Agent),Beats 占用资源少,适合于在各个服务器上搜集日志后传输给 Logstas…
暂无图片
编程学习 ·

Linux 基础

通常大数据框架都部署在 Linux 服务器上,所以需要具备一定的 Linux 知识。Linux 书籍当中比较著名的是 《鸟哥私房菜》系列,这个系列很全面也很经典。但如果你希望能够快速地入门,这里推荐《Linux 就该这么学》,其网站上有免费的电…
暂无图片
编程学习 ·

Windows2022 无线网卡装不上驱动

想来 Windows2022 和 windows10/11 的驱动应该差不多通用的,但是死活装不上呢? 搜一下,有人提到 “默认安装时‘无线LAN服务’是关闭的,如果需要开启,只需要在“添加角色和功能”中,选择开启“无线LAN服务…
暂无图片
编程学习 ·

【嵌入式面试宝典】版本控制工具Git常用命令总结

目录 创建仓库 查看信息 版本回退 版本检出 远程库 Git 创建仓库 git initgit add <file> 可反复多次使用&#xff0c;添加多个文件git commit -m <message> 查看信息 git status 仓库当前的状态git diff 差异对比git log 历史记录&#xff0c;提交日志--pret…
暂无图片
编程学习 ·

用Postman生成测试报告

newman newman是一款基于nodejs开发的可以运行postman脚本的工具&#xff0c;使用Newman&#xff0c;可以直接从命令运行和测试postman集合。 安装nodejs 下载地址&#xff1a;https://nodejs.org/en/download/ 选择自己系统相对应的版本内容进行下载&#xff0c;然后傻瓜式安…
暂无图片
编程学习 ·

Java面向对象之多态、向上转型和向下转型

文章目录前言一、多态二、引用类型之间的转换Ⅰ.向上转型Ⅱ.向下转型总结前言 今天继续Java面向对象的学习&#xff0c;学习面向对象的第三大特征&#xff1a;多态&#xff0c;了解多态的意义&#xff0c;以及两种引用类型之间的转换&#xff1a;向上转型、向下转型。  希望能…