计算机算法中的数字表示法——原码、反码、补码
目录
- 1.前言
- 2.研究数字表示法的意义
- 3.数字表示法
- 3.1 无符号整数
- 3.2 有符号数值
- 3.3 二进制补码(Two's Complement, 2C)
- 3.4 二进制反码(也称作 1 的补码, One's Complement, 1C)
- 3.5 减 1 表示法(Diminished one System, D1)
- 3.6 原码、反码、补码总结
1.前言
昨天有粉丝让我讲解下定点数和浮点数,本来这部分是打算在FPGA入门系列的最后面来讲的。作者想开的系列真的很多,比如开发FPGA需要学会相关软件Matlab、Vivado、ModelSim等等的使用,每个软件做一个系列;FPGA入门教程做一个系列;基础数字信号处理做一个系列;通信相关的系列;IP核使用详解系列;FPGA数字积木系列(自己设计的一些参数化IP)。但是这些无疑都会花大量的时间去构思和整理资料,会出的比较慢,请读者耐心等待。
这篇文章就先介绍定点数和浮点数的概念,因为要真正讲清楚还得从原码、补码和反码开始讲起。要仔细研究的建议去多看看相关书籍,讲清楚原理之后再讲Matlab里面计算的浮点数怎么转换为定点数到FPGA里面进行使用,以及FPGA里面计算的定点数,怎么在Matlab里面又转换为浮点数。
这里需要重点强调的是,原理虽然很枯燥,但是真的很重要,是绝对不能忽视的,如果原理弄的一知半解,就开始去做处理,后期该踩得坑一个也少不了。
2.研究数字表示法的意义
在计算机算法中,有两个基本设计准则是非常重要的:分别是数字表示法和代数运算的实现。例如:定点数或浮点数就是常用且可行的数字表示法。一些基本的运算,像加法器和乘法器,更为繁琐的运算,诸如求平方根和应用CORDIC算法计算角函数的有效实现,都要以可行的数字表示法为基础实现。
FPGA由于其物理位级编程结构的特点,提供了大量实现数字信号处理算法所需要的计算机算法。这恰好与带有定点多级累加器内核的可编程数字信号处理器(programmable digital signal processors,PDSP)相反。在FPGA设计中仔细地选择位宽就能够从本质上做到节约。
3.数字表示法
在工程的早期阶段,必须仔细考虑,确定是使用定点数还是浮点数更适合于解决问题。一般可以认为:定点数的实现具有更高的速度和更低廉的成本;而浮点数则具有更高的动态范围且不需要换算,这对较为复杂的算法可能更适合。下图给出了传统和非传统定点数和浮点数的数字表示法的一个概观。两套系统都由许多各自的标准所覆盖,当然,如果需要的话也可以以一种专有形式实现。

3.1 无符号整数
设 X X X 是 一个 N N N 位无符号二进制数, 则其范围是 [ 0 , 2 N − 1 ] \left[0,2^N-1\right] [0,2N−1], 表达式如下:
X = ∑ n = 0 N − 1 x n 2 n X=\sum_{n=0}^{N-1} x_n 2^n X=n=0∑N−1xn2n
其中 x n x_n xn 是 X X X 的第 n n n 位二进制数字(也就是 x n ∈ [ 0 , 1 ] x_n \in[0,1] xn∈[0,1] )。数字 x 0 x_0 x0 称作最低有效位(Least Significant Bit, LSB), 具有相当于个位的权重。数字 x N − 1 x_{N-1} xN−1 就是最高有效位(Most Significant Bit, MSB), 具有相当于 2 N − 1 2^{N-1} 2N−1 的权重。
3.2 有符号数值
在有符号数字表示法中, 数字和符号是单独表示的。第一位代表符号, 余下的 N − 1 N-1 N−1 位代表数字, 表达式如下:
X = { ∑ n = 0 N − 1 x n 2 n X ≥ 0 − ∑ n = 0 N − 1 x n 2 n X < 0 X= \begin{cases}\sum_{n=0}^{N-1} x_n 2^n & X \geq 0 \\ -\sum_{n=0}^{N-1} x_n 2^n & X<0\end{cases} X={∑n=0N−1xn2n−∑n=0N−1xn2nX≥0X<0
表达式的范围是 [ − 2 N − 1 , 2 N − 1 ] \left[-2^{N-1}, 2^{N-1}\right] [−2N−1,2N−1], 有符号数字表示法的优点就是简化了溢出的问题, 但缺点就是加法需要根据哪一个操作数更大来进行区分运算。
3.3 二进制补码(Two’s Complement, 2C)
有符号整数的 N N N 位二进制补码表达式如下:
X = { ∑ ∞ − 0 N − 1 x n 2 n X ≥ 0 2 k − ∑ n = 0 1 − 1 x n 2 n X < 0 X= \begin{cases}\sum_{\infty-0}^{N-1} x_n 2^n & X \geq 0 \\ 2^k-\sum_{n=0}^{1-1} x_n 2^n & X<0\end{cases} X={∑∞−0N−1xn2n2k−∑n=01−1xn2nX≥0X<0
其范围是 [ − 2 N − 1 , 2 N − 1 − 1 ] \left[-2^{N-1}, 2^{N-1}-1\right] [−2N−1,2N−1−1]。目前数字信号处理领域,最常用的就是用二进制补码来表示有符号数。这是由于它可以累加多个有符号数,且最终结果也在N位范围内,即可以忽略一切算术上的溢出。
例如,我们计算两个3位数的差(3-2=?):
3 10 ↔ 01 1 2 C − 2 10 ↔ 11 0 2 C 1 10 ↔ 1.00 1 2 C \begin{array}{rrr} 3_{10} & \leftrightarrow & 011_{2 C} \\ -2_{10} & \leftrightarrow & 110_{2 C} \\ 1_{10} & \leftrightarrow & 1.001_{2 C} \end{array} 310−210110↔↔↔0112C1102C1.0012C
溢出可以忽略。所有的计算都是取模 2 N 2^N 2N 。这样就有可能出现不能够正确表示中间值的情形,但只要最终值有效, 结果就是正确的。例如计算 3 位的数字 2 + 2 − 3 2+2-3 2+2−3, 会得到一个中间值 010 + 010 = 10 0 2 C 010+010=100_{2 C} 010+010=1002C, 也就是 − 4 10 -4_{10} −410, 但是结果 100 − 011 = 100 + 101 = 00 1 2 C 100-011=100+101=001_{2 C} 100−011=100+101=0012C, 是正确的。
二进制补码还可以用来实现模 2 N 2^N 2N 的算法, 而且不需要在算法中作任何改动。
3.4 二进制反码(也称作 1 的补码, One’s Complement, 1C)
N N N 位二进制反码数字表示法可以表示的整数范围是 [ − 2 N − 1 − 1 , 2 N − 1 − 1 ] \left[-2^{N-1}-1,2^{N-1}-1\right] [−2N−1−1,2N−1−1] 。在二进制反码中,正整数和负整数除了符号位之外具有相同的表示方法。那么“0”就有正的和负的,两个表达式。二进制反码中有符号数的标准表达式如下:
X = { ∑ n = 0 N − 1 x n 2 n X ≥ 0 2 N − 1 − ∑ n = 0 N − 1 x n 2 n X < 0 X= \begin{cases}\sum_{n=0}^{N-1} x_n 2^n & X \geq 0 \\ 2^N-1-\sum_{n=0}^{N-1} x_n 2^n & X<0\end{cases} X={∑n=0N−1xn2n2N−1−∑n=0N−1xn2nX≥0X<0
请看下面的简单示例:
3 10 ↔ 0 1 1 1 C − 2 10 ↔ 1 0 1 1 C 1 10 ↔ 1. 0 0 0 1 C 进位 → → → 1 1 C 1 10 ↔ 0 0 1 1 C \begin{array}{rrrrrr} 3_{10} & \leftrightarrow & & 0 & 1 & 1_{1 C} \\ -2_{10} & \leftrightarrow & & 1 & 0 & 1_{1 C} \\ 1_{10} & \leftrightarrow & 1. & 0 & 0 & 0_{1 C} \\ 进位 & & \rightarrow & \rightarrow & \rightarrow & 1_{1 C} \\ 1_{10} & \leftrightarrow & & 0 & 0 & 1_{1 C} \end{array} 310−210110进位110↔↔↔↔1.→010→0100→011C11C01C11C11C
在二进制反码中需要, “进位问绕(carry wrap-around)” 加法。在最高有效位与最低有效位相加得到正确结果时, 就会出现进位。
尽管如此, 这种数字表示法还走能够有效地实现模 2 N − 1 2^N-1 2N−1 运算, 而且不需要校正。因此二进制反码在实现特定的 DSP 算法(例如: 整数计算不 2 N − 1 2^N-1 2N−1 的 Mersenne 变换)时, 还是有其特殊价值的。
3.5 减 1 表示法(Diminished one System, D1)
减1表示法是一种有偏移的数学表示法。正整数与二.进制补码相比减少了 1。 N N N 位 D1数值范围是 [ − 2 N − 1 , 2 N − 1 ] ( \left[-2^{N-1}, 2^{N-1}\right]( [−2N−1,2N−1]( 不含 0 ) ) ) 。D1 数字表示法的编码规则定义如下:
X = { ∑ n = 0 A − 1 x n 2 n − 1 X ≥ 0 2 N − ∑ n = 0 N − 1 x n 2 n X < 0 2 N X = 0 X= \begin{cases}\sum_{n=0}^{A-1} x_n 2^n-1 & X \geq 0 \\ 2^N-\sum_{n=0}^{N-1} x_n 2^n & X<0 \\ 2^N & X=0\end{cases} X=⎩ ⎨ ⎧∑n=0A−1xn2n−12N−∑n=0N−1xn2n2NX≥0X<0X=0
从下面两个 D1 数相加可以看到, 对于 D1 而言还必须计算补码和颠倒进位的加法。
3 10 ↔ 0 1 0 D 1 − 2 10 ↔ 1 1 0 D 1 1 10 ↔ 1. 0 0 0 D 1 进位 → . -1 → 0 D 1 1 10 ↔ 0 0 0 D 1 \begin{array}{rrrrrr} 3_{10} & \leftrightarrow & & 0 & 1 & 0_{D 1} \\ -2_{10} & \leftrightarrow & & 1 & 1 & 0_{D 1} \\ 1_{10} & \leftrightarrow & 1. & 0 & 0 & 0_{D 1} \\ 进位 & & \rightarrow &\fbox{. -1} & \rightarrow & 0_{D 1} \\ 1_{10} & \leftrightarrow & & 0 & 0 & 0_{D 1} \end{array} 310−210110进位110↔↔↔↔1.→010. -10110→00D10D10D10D10D1
D1 数不需要在算法上作任何改动就能够有效地实现模 2 N + 1 2^N+1 2N+1 运算。比如可以利用这一结论在 2 N + 1 2^N+1 2N+1 计算环中实现费尔出 NTT(Fermat Network Transfer Table, Fermat 网络传输表)。
3.6 原码、反码、补码总结
上面说了这么多,又是公式又是例子的估计很多人都开始晕了,现在直接总结口诀如下:
对于有符号数而言:
1.二进制的最高位是符号位:0表示正数,1表示负数(口诀0——>0,1——>-)。
2.正数的原码、反码、补码都是一样的(三码合一)。
3.负数的反码 = 它的原码符号位不变,其他位取反(0——>1,1——>0)。
4.负数的补码 = 它的反码 + 1,负数的反码 = 负数的补码 - 1。
5.0的反码、补码都是0。
6.在计算机运算的时候,都是以补码的方式来运算的。
7.当我们看运算结果的时候,要看它的原码。

关注微信公众号获取更多资讯:3.4 二进制反码(也称作 1 的补码, Ones Complement, 1C)3.5 减 1 表示法(Diminished one System, D1)3.6 原码、反码、补码总结 1.前言 昨天有粉丝让我讲解下定…...
BGP策略实验
一、实验要求 二、实验分析 1.先配置IP 2.再配置BGP 3.配置BGP策略 三、实验过程 要求 1. [r4]ip ip-prefix aa permit 192.168.10.0 24 [r4]route-policy aa permit node 10 [r4-route-policy]if-match ip-prefix aa [r4-route-policy]apply preferred-value 100 [r4]rout…...
目标检测 | R-CNN、Fast R-CNN与Faster R-CNN理论讲解
☀️教程:霹雳吧啦Wz ☀️链接:https://www.bilibili.com/video/BV1af4y1m7iL?p1&vd_sourcec7e390079ff3e10b79e23fb333bea49d 一、R-CNN R-CNN(Region with CNN feature)是由Ross Girshick在2014年提出的,在PAS…...
【busybox记录】【shell指令】mkdir
目录 内容来源: 【GUN】【mkdir】指令介绍 【busybox】【mkdir】指令介绍 【linux】【mkdir】指令介绍 使用示例: 创建文件夹 - 默认 创建文件夹 - 创建的同时指定文件权限 创建文件夹 - 指定多级文件路径,如果路径不存在,…...
SQL刷题笔记day6-1
1从不订购的客户 分析:从不订购,就是购买订单没有记录,not in 我的代码: select c.name as Customers from Customers c where c.id not in (select o.customerId from Orders o) 2 部门工资最高的员工 分析:每个部…...
KITTI数据中pose含义
Folder ‘poses’: The folder ‘poses’ contains the ground truth poses (trajectory) for the first 11 sequences. This information can be used for training/tuning your method. Each file xx.txt contains a N x 12 table, where N is the number of frames of this …...
C++模拟实现stack和queue
1 stack 1.1概念 stl栈 1.2栈概念 1.3代码 2 queue 2.1概念 stl队列 2.2队列概念 2.3代码...
awtk踩坑记录一:awtk-web build.py编译过程笔记
工作需求,接触了awtk, 要求把界面部署到web上,期间因为各种编译问题卡的半死,提了不少issue, 经过几天补课,把项目的编译结构给摸了一遍,做个记录,也希望能帮到有同样问题的朋友。 之前python只是略接触过…...
docker容器中解决中文乱码
1. 找到dockerfile文件 2. 编辑Dockerfile 添加 ENV LANG en_US.UTF-8 ENV LANGUAGE en_US:en ENV LC_ALL en_US.UTF-8 3. 生成新的镜像文件 FROM java17_yinpeng:latest MAINTAINER YP <2064676101QQ.COM> ADD jiquan_online_chat.jar jiquan_online_chat #CM…...
Javascript 位运算符(,|,^,<<,>>,>>>)
文章目录 一、什么是位运算?二、如何使用1. 位与(AND):&用途(1)数据清零(2)判断奇偶 2. 位或(OR):|用途(1)向下取整 3…...
Golang项目代码组织架构实践
Golang在项目结构上没有强制性规范,虽然这给了开发者很大的自由度,但也需要自己沉淀一套可行的架构。本文介绍了一种项目布局,可以以此为参考设计适合自己的 Golang 项目组织模式。原文: Golang Project Layout Go 有很多强制的或是约定俗成的…...
网工内推 | 国企信息安全工程师,CISP认证优先
01 浙江省公众信息产业有限公司 🔷招聘岗位:安全运营工程师 🔷职责描述: 1. 负责公司内部安全运营平台及其子系统的安全事件管理、事件发现分析、应急响应和系统维护等; 2. 负责风险和漏洞管理,包括漏洞预…...
RAG 高级应用:基于 Nougat、HTML 转换与 GPT-4o 解析复杂 PDF 内嵌表格
一、前言 RAG(检索增强生成)应用最具挑战性的方面之一是如何处理复杂文档的内容,例如 PDF 文档中的图像和表格,因为这些内容不像传统文本那样容易解析和检索。前面我们有介绍过如何使用 LlamaIndex 提供的 LlamaParse 技术解析复…...
《TCP/IP网络编程》(第十二章)I/O复用(2)
下面是基于I/O复用的回声服务器端和客户端代码 1.Linux系统 服务器端代码 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> // POSIX标准定义的通用函数,如close() #include <arpa/inet.h> //…...
AI企业需要“联盟营销”?一文带你探索AI企业营销新玩法!
为什么联盟营销对AI业务有较大优势 联盟营销在电商领域、saas领域与其他产品领域同样有效。在AI业务中,它有效的原因与其他领域大不相同。 高好奇心和试用率 AI领域是创新的热点。它吸引了一群渴望探索和尝试每一项新技术的人群。这种蓬勃的好奇心为聪明的AI企业提…...
你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解
目录 一、onMounted的前世今生 1.1、onMounted是什么 1.2、onMounted在vue2中的前身 1.2.1、vue2中的onMounted 1.2.2、Vue2与Vue3的onMounted对比 1.3、vue3中onMounted的用法 1.3.1、基础用法 1.3.2、顺序执行异步操作 1.3.3、并行执行多个异步操作 1.3.4、执行一次…...
JavaWeb基础(一)-IO操作
Java I/O工作机制: 注:简要笔记,示例代码可能较少,甚至没有。 1、Java 的 I/O 类库的基本架构。 Java 的 I/O 操作类在包 java.io 下,大概有将近80个类,这些类大概可以分为如下四组。 基于字节操作的…...
拼多多(PDD)社招一面原题
未成年游戏退费 5 月 28 日,中国互联网协会发布《未成年人网络游戏服务消费管理要求(征求意见稿)》团体标准。 该标准是游戏行业首个完整的消费管理规范,可用于未成年人游戏消费退费纠纷解决,也可为相关行政部门、司法…...
类中使用QtConcurrent::run
在QtConcurrent::run中调用类的成员函数时,你需要注意几个关键点: 对象生命周期:你需要确保在QtConcurrent::run调用的整个期间,类对象都是有效的。如果对象在成员函数执行期间被销毁,将会导致未定义行为。成员函数访…...
基于深度学习的中文情感分析系统python flask
基于python的毕业设计 基于深度学习的中文情感分析系统(flask)(源码说明文档演示) 毕业设计课程设计期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
