原码、补码、反码、移码是什么?

计算机很多术语翻译成中文之后,不知道是译者出于什么目的,往往将其翻译成一个很难懂的名词。

奇怪的数学定义

下面是关于原码的“吐槽”,可以当作扩展。你可以不看,直接去下一章,没有任何影响。
原码的吐槽放在前面是防止读者看完原码,然后看半天才看到补码,影响阅读体验。

某些书描述“原码”的时候很“奇怪”,你可能在某些书上见到过下面这样很难理解的描述(下图截自原码 - 维基百科):
请添加图片描述

这玩意是数论里的等价类或者群论里的空间的表达方式,也就是计算机里常出现的“模运算”。或者还有个更高级的名字:散列(因为很多散列算法就是模运算,然后用的等价类的思想)。

等价类:3 mod 21 mod 2的结果都为1,所以都等于[1],也就是31都是关系mod 21等价类。

那上面的那一堆是什么意思呢?

以整数原码为例,X是一个数,范围不定。

[+1011]的意思是和+1011等价的所有数:
X m o d 2 n = 1011 X mod 2^n = 1011 Xmod2n=1011

比如 n > 4 n>4 n>4的时候 2 n > 0 b 1111 2^n>0b1111 2n>0b1111
1011 m o d 2 n = 1011 ( 2 n + 1011 ) m o d 2 n = 1011 1011 mod 2^n = 1011\\ (2^n + 1011) mod 2^n = 1011 1011mod2n=1011(2n+1011)mod2n=1011

[-1011]的意思是和(2^{n-1} - 1011)等价的所有类:

( 2 n − 1 − X ) m o d 2 n = 1011 (2^{n-1} - X) mod 2^n = 1011 (2n1X)mod2n=1011

比如是 8 位的数字:
( 2 8 − 1 − ( − 1011 ) ) m o d 2 n = ( 10000000 + 1011 ) ) m o d 11111111 = 10001011 (2^{8-1} - (-1011)) mod 2^n =\\ (10000000 + 1011)) mod 11111111 = 10001011 (281(1011))mod2n=(10000000+1011))mod11111111=10001011

这是教材,不是论文,而且一般论文也不用这么说吧?

这种表达方式唯一的好处就是让你理解溢出之后该怎么处理,因为取模运算的值就是溢出后得到的值。

说实话这种表达方式就不应该出现在任何现代教材中,哪怕是很多数学分析的书都不会这样描述数的。我不知道这种用法最早出现在哪里,但是欧美一些常见的计算机组成与设计教材中没有出现过这种用法,也就是说并不是盲目学来的。

不论是“true code”还是“true form”都在英文搜索中难以找到。WiKi “有符号数处理”中,“原码”对应的是“符号及值(sign & magnitude)”,英文版直接就是“Sign–magnitude”。这玩意的在一些教材中的翻译是“符号和幅值表达法”,看看这个名字多清晰和直白。

这个方法读者理解就好,没必要学,后文也完全不使用这个方法,怎么容易理解怎么来。但计算机科学确实有很多算法使用了等价类的概念,所以如果你要走算法方向,还是要看看的。

原码

原码就是我们常用的数,在计算机中就是用二进制表示的十进制数,不论正负、不论整数还是小数。

n位原码就是用最高位(小端就是最右位)当作符号位(0为正数,1为负数),关于0对称范围内的数( − 2 n ~ 2 n -2^n~2^n 2n2n),比如-4~4-16~16,范围的两个端点关于0对称,正负数的个数相同。

补码(2’s complement)

n位补码就是用最高位(小端就是最右位)当作符号位(0为正数,1为负数)关于0不对称范围内的数( − 2 n − 1 ~ ( 2 n − 1 − 1 ) -2^{n-1}~(2^{n-1}-1) 2n1(2n11)),比如-16~15,范围的两个端点关于0不对称。

这里概念很容易和和其他码搞混,比如原码。

但其实只用记住一个关键点:补码的-11111,而原码是1001

换言之,从零值的“生长”来说:

  • 原码相当于少一位(最大的那位)的无符号数。抛开符号位-xx的表达是一样的,所以上下限的绝对值是一样的。
  • 补码从0开始增减,0b0000-1,借位算出是0b1111。但是+1增的时候,要注意不能让最大位为1,所以上限比下限绝对值少1

补码是现在主流的格式,所以各种考试也主要考补码。所以只讲一下补码的计算。

补码计算的时候,加减法要带着符号位进行,乘除法就是左移补0,右移补符号位

比如:

  • 1011*2,得到的是0110
  • 1011/2,得到的是1101
  • 0011+0011,也就是3+3=6=0110
 0011
+0011
-------0110
  • 0011-0111,也就是3-7=-4=1100
 0011
-0111
-------1100

用加减法可以很容易得到-x对应的二进制,反之亦然。

举个例子,我要计算出1111 0100的的十进制,那么可以先计算出和0(0000 0000)的差(前 4 位相同,甚至可以不用写):

 0000 0000
-1111 0100
-----------0000 1100

得到12,加上符号-(原二进制符号位为1,也就是负的),那么最后得到-12

反之,我们想计算出-8的二进制,也就是和08(0000 1000),那么就可以:

 0000 0000
-0000 1000
-----------1111 1000

是不是很简单。

反码(1’s complement)

反码中,一个数的相反数就是按位取反,1001,这也是名字的由来。

比如1(00000001)按位取反,得到-1(11111110)。

所以反码和原码一样,是关于0对称的,所以正负数的个数相同。但是不同之处在于:反码有两个0,正0(0000)和负0(1111)。

在无符号数的反码中,x按位取反为 2 n − 1 − x 2^n-1-x 2n1x

因为无符号反码增长就是从0一直加,所以最大值是 2 n − 1 2^n-1 2n1。而按位取反就相当于从尾部往前倒。

你可以观察一下下面这个表格,再看看我的说法,你就会理解了。
请添加图片描述

反码(1’s complement)早期设备用的多,现在用补码(2’s complement)是主流,因为反码计算的时候更麻烦一些,只是在计算一些科学计算的时候更有优势罢了。

看开头的数字也可以看出顺序来(啊对,这两个英文中的数字就是版本,这你能想到哈哈哈哈)。

移码(Offset binary)

移码又称“偏移表示法”,这个方法现在是上面浮点数用的多,比如 IEEE 754。

移码从0000开始递增,依旧使用最高位位符号为,只不过这里1表示正数
0表示负数。与前面的几种方法相反。

有符号移码最小的负数是0000,最大的整数是111101000

这里可能好奇名字中“偏移”的意思,其实就是“给数加上一个偏移数后,使其具有非负的表达形式”。

比如上面的0,加上一个偏移1000,得到的就是1000,也就是0,非负。

关于这部分,浮点数中再细说吧。

希望能帮到有需要的人~

参考资料

《Computer Organization and Design MIPS Edition: The Hardware/Software Interface Fifth Edition》:如果你要学习计算机结构的话,这本书要比国内的很多教材好,但是翻译的确实不太行。

原码 - 维基百科

Signed number representations - 维基百科

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

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

相关文章

配置单区域OSPF

目录 引言 一、搭建基础网络 1.1 配置网络拓扑图如下 1.2 IP地址表 二、测试每个网段都能单独连通 2.1 PC0 ping通Router1所有接口 2.2 PC1 ping通Router1所有接口 2.3 PC2 ping通Router2所有接口 2.4 PC3 ping通Router2所有接口 2.5 PC4 ping通Router3所有接口 2.…

Git仓库拆分和Merge

1. 问题背景 我们原先有一个项目叫open-api,后来想要做租户独立发展,每个租户独立成一个项目,比如租户akc独立部署一个akc-open-api,租户yhd独立部署一个yhd-open-api,其中大部分代码是相同的,少量租户定制…

2024牛客暑期多校训练营1——A,B

题解&#xff1a; 更新&#xff1a; k1的时候要乘n 代码&#xff1a; #include<bits/stdc.h> #define int long long using namespace std; const int N5e35; typedef long long ll; typedef pair<int,int> PII; int T; int n,m,mod; int fac[N][N]; int dp[N][…

笔记:Few-Shot Learning小样本分类问题 + 孪生网络 + 预训练与微调

内容摘自王老师的B站视频&#xff0c;大家还是尽量去看视频&#xff0c;老师讲的特别好&#xff0c;不到一小时的时间就缕清了小样本学习的基础知识点~Few-Shot Learning (1/3): 基本概念_哔哩哔哩_bilibili Few-Shot Learning&#xff08;小样本分类&#xff09; 假设现在每类…

【Linux】基础I/O——动静态库的制作

我想把我写的头文件和源文件给别人用 1.把源代码直接给他2.把我们的源代码想办法打包为库 1.制作静态库 1.1.制作静态库的过程 我们先看看怎么制作静态库的&#xff01; makefile 所谓制作静态库 需要将所有的.c源文件都编译为(.o)目标文件。使用ar指令将所有目标文件打包…

谷粒商城实战笔记-38-前端基础-Vue-指令-单向绑定双向绑定

文章目录 一&#xff0c;插值表达式注意事项1&#xff1a;不适合复杂的逻辑处理注意事项2&#xff1a;插值表达式支持文本拼接注意事项3&#xff1a;插值表达式只能在标签体中 二&#xff0c;v-html和v-textv-textv-html区别总结&#xff1a;最佳实践 三&#xff0c;v-model复选…

FastAPI 学习之路(五十六)将token缓存到redis

在之前的文章中&#xff0c;FastAPI 学习之路&#xff08;二十九&#xff09;使用&#xff08;哈希&#xff09;密码和 JWT Bearer 令牌的 OAuth2&#xff0c;FastAPI 学习之路&#xff08;二十八&#xff09;使用密码和 Bearer 的简单 OAuth2&#xff0c;FastAPI 学习之路&…

阵列信号处理学习笔记(二)--空域滤波基本原理

阵列信号 阵列信号处理学习笔记&#xff08;一&#xff09;–阵列信号处理定义 阵列信号处理学习笔记&#xff08;二&#xff09;–空域滤波基本原理 文章目录 阵列信号前言一、阵列信号模型1.1 信号的基本模型1.2 阵列的几何构型1.3 均匀直线阵的阵列信号基本模型 总结 前言…

嵌入式面试总结

C语言中struct和union的区别 struct和union都是常见的复合结构。 结构体和联合体虽然都是由多个不同的数据类型成员组成的&#xff0c;但不同之处在于联合体中所有成员共用一块地址空间&#xff0c;即联合体只存放了一个被选中的成员&#xff0c;结构体中所有成员占用空间是累…

【网络】windows和linux互通收发

windows和linux互通收发 一、windows的udp客户端代码1、代码剖析2、总体代码 二、linux服务器代码三、成果展示 一、windows的udp客户端代码 1、代码剖析 首先我们需要包含头文件以及lib的一个库&#xff1a; #include <iostream> #include <WinSock2.h> #inclu…

【模板代码】用于编写Threejs Demo的模板代码

基础模板代码 使用须知常规模板代码常规Shader模板代码 使用须知 本模板代码&#xff0c;主要用于编写Threejs的Demo&#xff0c;因为本人在早期学习的过程中&#xff0c;大量抄写Threejs/examples下的代码以及各个demo站的代码&#xff0c;所以养成了编写Threejs的demo的习惯…

SAP 采购订单 Adobe 消息输出

目录 1 简介 2 业务数据例子 3 选择增强 & 代码 1&#xff09;BADI: MM_PUR_S4_PO_MODIFY_HEADER 2&#xff09;BADI: MM_PUR_S4_PO_MODIFY_ITEM 4 自定义 Adobe form 1&#xff09;PO Master form 2&#xff09;PO form 5 前台主数据配置 6 后台配置 1&#xf…

掌握Rust:函数、闭包与迭代器的综合运用

掌握Rust&#xff1a;函数、闭包与迭代器的综合运用 引言&#xff1a;解锁 Rust 高效编程的钥匙函数定义与模式匹配&#xff1a;构建逻辑的基石高阶函数与闭包&#xff1a;代码复用的艺术迭代器与 for 循环&#xff1a;高效数据处理的引擎综合应用案例&#xff1a;构建一个简易…

【LeetCode】day15:110 - 平衡二叉树, 257 - 二叉树的所有路径, 404 - 左叶子之和, 222 - 完全二叉树的节点个数

LeetCode 代码随想录跟练 Day15 110.平衡二叉树257.二叉树的所有路径404.左叶子之和222.完全二叉树的节点个数 110.平衡二叉树 题目描述&#xff1a; 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树 平衡二叉树的定义是&#xff0c;对于树中的每个节点&#xff0c;其左右…

qt自定义控件(QLabel)

先创建自定义控件类painter_label 1.自定义类必须给基类传入父窗口指针 2.重写控件中的方法 3.在UI中创建一个QLabel,右键“提升为”&#xff0c;输入类名

动画革命:Lottie如何改变我们对移动应用交互的认知

在数字世界的浩瀚星空中&#xff0c;每一个像素都跃动着无限创意与想象的火花。当静态的界面遇上动态的魔法&#xff0c;一场视觉盛宴便悄然开启。今天&#xff0c;让我们一同揭开一位幕后英雄的神秘面纱——Lottie&#xff0c;这个在UI/UX设计界掀起波澜的动画利器&#xff0c…

SVN与Git功能差异对比分析

最近在调研学习Git管理和分支模型相关内容&#xff0c;外延到了SVN和Git差异、工作原理等相关细节&#xff0c;学习整理如下。 SVN&#xff08;Subversion&#xff09;与 Git 的最大不同&#xff0c;主要包括以下几个方面&#xff1a; 交流探讨&#xff0c;加入群聊【Java学习…

51.2T 800G 以太网交换机,赋能AI开放生态

IB与以太之争 以太网替代IB趋势明显。据相关报告&#xff1a;2024年TOP500的超算中&#xff0c;采用以太网方案占比48.5%&#xff0c;InfiniBand占比为39.2%&#xff0c;其中排名前6的超算中已有5个使用以太网互联。 开放系统战胜封闭系统仅是时间问题。我们已经看到&#xf…

钡铼EdgeIO系统BL206对接MQTT、Modbus TCP、OPC UA

钡铼EdgeIO系统BL206提供双网口支持交换机级联功能&#xff0c;支持标准MQTT协议、Modbus TCP协议、OPC UA协议&#xff0c;由耦合器与IO模块组成&#xff0c;采用Web配置&#xff0c;内置云驱动、可编程逻辑控制功能&#xff0c;用户点击即可连接云平台。耦合器自带诊断功能&a…

网络结构-组件-AI(九)

深度学习网络组件 RNN公式讲解计算示意图讲解 CNN计算示意 Normalization(归一化层)Normalization常见两种方式 Dropout层 RNN 循环神经网络&#xff08;recurrent neural network&#xff09; 主要思想&#xff1a; 即将整个序列划分成多个时间步&#xff0c;将每一个时间步的…