源码,补码,反码
引用 https://www.cnblogs.com/baiqiantao/p/7442907.html#原码-反码-补码
原码,补码,反码的定义?
原码,补码,反码都是二进制数字,是一种计算机也能看懂的数字,这个二进制数字使用左边起第一位为符号位,这个符号位用来表明这个二进制数字是正数还是负数。
规定正数符号位为0,负数符号位为1.
原码的定义
原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。
反码的定义
反码:正数的反码就是原码,负数的反码就是在原码的基础上符号位不变,其他位按位取反。
补码的定义
补码:正数的补码就是原码,负数的补码就是在反码的基础上按照正常的加法运算+1;
直接求原码的补码有一个简单的方式:符号位不变,按位从最低位开始直至遇到第一个1之前都保留原数,并且保留第一个1,其他位按位取反。
例如:
原码:10010100 反码:11101011 补码:11101100
补码:11101100
原码,补码,反码的应用
在了解原码,补码,反码的应用前我们需先了解一些基本的概念。
基本概念
机器数和符号位
机器数的定义:一个数的二进制表示形式就是一个机器数,机器数是有符号位的。
机器数就是原码。
真值
机器数因为有一位符号位,所以机器数的形式值并不是机器数的值,因此这里引入了真值的概念,将带符号位的机器数对应的真正数值称为机器数的真值。
为什么要使用原码,补码,反码
现在我们知道了,计算机可以有三种编码方式表示一个数,对于正数因为三种编码方式的结果都相同,所以不需要过多解释。但是对于负数,其原码、反码和补码是完全不同的。既然原码才是被人脑直接识别并用于计算表示方式,为何还会有反码和补码呢?
首先,希望能用符号位代替减法
对于原码,人脑是清楚第一位是符号位的,所以直接使用人脑计算使用原码是足够了。由于加减乘除是计算机最基本的操作,因此能希望这些操作设计的足够简单(计算机辨别符号位会让计算机基础电路设计更为复杂)。因此人们希望能直接将符号位也可以直接参与运算。
于是人们就开始探索将符号位参与运算并且只保留加法的方法。
但是直接使用原码计算会有一些问题:
首先看原码:
1-1=1+(-1)=00000001+10000001=10000010=-2
如果让符号位参与计算,对于减法是不正确的。
于是反码的出现解决了这个问题,但是遇到0时还有一些问题
1-1=1+(-1)=00000001(原码)+10000001(原码)=00000001(反码)+11111110(反码)=11111111(反码)=10000000(原码)=-0
发现用反码计算减法,结果的真值部分是正确的,而唯一的问题其实就出现在0这个特殊的数值上。虽然人们理解上+0和-0是一样的,但是0带符号是没有任何意义的,而且会有[0000_0000]原和[1000_0000]原两个编码表示0。
因此补码补足了这个遗憾
1-1=1+(-1)=00000001(原码)+10000001(原码)=00000001(反码)+11111110(反码)=00000001(补码)+11111111(补码)=00000000(补码)=00000000(原码)=0
这样0用[0000_0000]表示, 而以前出现问题的-0则不存在了。
并且,还有意外收获..
除此之外,还可以用 [1000_0000]补 表示-128:
-1-127=(-1)+(-127)=10000001(原码)+11111111=11111110(反码)+10000000=11111111(补码)+10000001=10000000(补码)
注意-128没有原码和反码表示
所以,使用补码不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数,这就是为什么8位二进制数使用原码和反码表示时范围是[-127,127],而使用补码表示时范围是[-128,127]
因为机器使用补码,所以对于编程中常用到的32位int类型可以表示范围是 [-2^31, 2^31-1] ,因为第一位表示的是符号位,而使用补码表示时又可以多保存一个最小值。
原文地址:https://www.cnblogs.com/planted/p/15175447.html
- 3399: [Usaco2009 Mar]Sand Castle城堡
- 遗传算法(1)
- LOJ#6284. 数列分块入门 8
- 3713: [PA2014]Iloczyn
- 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)
- SQL Server 深入解析索引存储(下)
- 2751: [HAOI2012]容易题(easy)
- codevs3002 石子归并 3
- 算法模板——计算几何2(二维凸包——Andrew算法)
- 算法模板——splay区间反转 2
- 算法模板——Dinic网络最大流 2
- 1935: [Shoi2007]Tree 园丁的烦恼
- 1339 / 1163: [Baltic2008]Mafia
- 4010: [HNOI2015]菜肴制作
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Angular jasmine.expect单步调试
- 第008课 第1个ARM裸板程序及引申(点亮LED灯)
- SharedPreferences VS MMKV
- 第009课 gcc和arm-linux-gcc和Makefile
- Go 每日一库之 quicktemplate
- 第010课 掌握Jz2440_ARM芯片时钟体系
- 第011课 Jz2400串口(UART)的使用
- 面试官看完我手写的单例直接惊呆了!
- 安利几个JS开发小技巧
- 深入理解Pod(一)
- [902]python list排序
- 第012课 内存控制器与SDRAM
- 一篇文章教给你Bypass学习基础
- 第013课 S3c2440代码重定位详解
- [901]sqlite数据库的导出与导入