​​【收录 Hello 算法】3.3 数字编码

news2024/11/21 11:03:42

目录

3.3   数字编码 

3.3.1   原码、反码和补码

3.3.2   浮点数编码


3.3   数字编码 

Tip

在本书中,标题带有 * 符号的是选读章节。如果你时间有限或感到理解困难,可以先跳过,等学完必读章节后再单独攻克。

3.3.1   原码、反码和补码

在上一节的表格中我们发现,所有整数类型能够表示的负数都比正数多一个,例如 byte 的取值范围是 [−128,127] 。这个现象比较反直觉,它的内在原因涉及原码、反码、补码的相关知识。

首先需要指出,数字是以“补码”的形式存储在计算机中的。在分析这样做的原因之前,首先给出三者的定义。

  • 原码:我们将数字的二进制表示的最高位视为符号位,其中 0 表示正数,1 表示负数,其余位表示数字的值。
  • 反码:正数的反码与其原码相同,负数的反码是对其原码除符号位外的所有位取反。
  • 补码:正数的补码与其原码相同,负数的补码是在其反码的基础上加 1 。

图 3-4 展示了原码、反码和补码之间的转换方法。

原码、反码与补码之间的相互转换

图 3-4   原码、反码与补码之间的相互转换

原码(sign-magnitude)虽然最直观,但存在一些局限性。一方面,负数的原码不能直接用于运算。例如在原码下计算 1+(−2) ,得到的结果是 −3 ,这显然是不对的。

1+(−2)→00000001+10000010=10000011→−3

为了解决此问题,计算机引入了反码(1's complement)。如果我们先将原码转换为反码,并在反码下计算 1+(−2) ,最后将结果从反码转换回原码,则可得到正确结果 −1 。

原码原码反码反码反码原码原码原码反码反码反码原码1+(−2)→00000001(原码)+10000010(原码)=00000001(反码)+11111101(反码)=11111110(反码)=10000001(原码)→−1

另一方面,数字零的原码有 +0 和 −0 两种表示方式。这意味着数字零对应两个不同的二进制编码,这可能会带来歧义。比如在条件判断中,如果没有区分正零和负零,则可能会导致判断结果出错。而如果我们想处理正零和负零歧义,则需要引入额外的判断操作,这可能会降低计算机的运算效率。

+0→00000000−0→10000000

与原码一样,反码也存在正负零歧义问题,因此计算机进一步引入了补码(2's complement)。我们先来观察一下负零的原码、反码、补码的转换过程:

原码反码补码原码反码补码−0→10000000(原码)=11111111(反码)=100000000(补码)

在负零的反码基础上加 1 会产生进位,但 byte 类型的长度只有 8 位,因此溢出到第 9 位的 1 会被舍弃。也就是说,负零的补码为 00000000 ,与正零的补码相同。这意味着在补码表示中只存在一个零,正负零歧义从而得到解决。

还剩最后一个疑惑:byte 类型的取值范围是 [−128,127] ,多出来的一个负数 −128 是如何得到的呢?我们注意到,区间 [−127,+127] 内的所有整数都有对应的原码、反码和补码,并且原码和补码之间可以互相转换。

然而,补码 10000000 是一个例外,它并没有对应的原码。根据转换方法,我们得到该补码的原码为 00000000 。这显然是矛盾的,因为该原码表示数字 0 ,它的补码应该是自身。计算机规定这个特殊的补码 10000000 代表 −128 。实际上,(−1)+(−127) 在补码下的计算结果就是 −128 。

原码原码反码反码补码补码补码原码原码反码反码补码补码补码(−127)+(−1)→11111111(原码)+10000001(原码)=10000000(反码)+11111110(反码)=10000001(补码)+11111111(补码)=10000000(补码)→−128

你可能已经发现了,上述所有计算都是加法运算。这暗示着一个重要事实:计算机内部的硬件电路主要是基于加法运算设计的。这是因为加法运算相对于其他运算(比如乘法、除法和减法)来说,硬件实现起来更简单,更容易进行并行化处理,运算速度更快。

请注意,这并不意味着计算机只能做加法。通过将加法与一些基本逻辑运算结合,计算机能够实现各种其他的数学运算。例如,计算减法 𝑎−𝑏 可以转换为计算加法 𝑎+(−𝑏) ;计算乘法和除法可以转换为计算多次加法或减法。

现在我们可以总结出计算机使用补码的原因:基于补码表示,计算机可以用同样的电路和操作来处理正数和负数的加法,不需要设计特殊的硬件电路来处理减法,并且无须特别处理正负零的歧义问题。这大大简化了硬件设计,提高了运算效率。

补码的设计非常精妙,因篇幅关系我们就先介绍到这里,建议有兴趣的读者进一步深入了解。

3.3.2   浮点数编码

细心的你可能会发现:int 和 float 长度相同,都是 4 字节 ,但为什么 float 的取值范围远大于 int ?这非常反直觉,因为按理说 float 需要表示小数,取值范围应该变小才对。

实际上,这是因为浮点数 float 采用了不同的表示方式。记一个 32 比特长度的二进制数为:

𝑏31𝑏30𝑏29…𝑏2𝑏1𝑏0

根据 IEEE 754 标准,32-bit 长度的 float 由以下三个部分构成。

  • 符号位 S :占 1 位 ,对应 𝑏31 。
  • 指数位 E :占 8 位 ,对应 𝑏30𝑏29…𝑏23 。
  • 分数位 N :占 23 位 ,对应 𝑏22𝑏21…𝑏0 。

二进制数 float 对应值的计算方法为:

val=(−1)𝑏31×2(𝑏30𝑏29…𝑏23)2−127×(1.𝑏22𝑏21…𝑏0)2

转化到十进制下的计算公式为:

val=(−1)S×2E−127×(1+N)

其中各项的取值范围为:

S∈{0,1},E∈{1,2,…,254}(1+N)=(1+∑𝑖=123𝑏23−𝑖2−𝑖)⊂[1,2−2−23]

IEEE 754 标准下的 float 的计算示例

图 3-5   IEEE 754 标准下的 float 的计算示例

观察图 3-5 ,给定一个示例数据 S=0 , E=124 ,N=2−2+2−3=0.375 ,则有:

 val =(−1)0×2124−127×(1+0.375)=0.171875

现在我们可以回答最初的问题:float 的表示方式包含指数位,导致其取值范围远大于 int 。根据以上计算,float 可表示的最大正数为 2254−127×(2−2−23)≈3.4×1038 ,切换符号位便可得到最小负数。

尽管浮点数 float 扩展了取值范围,但其副作用是牺牲了精度。整数类型 int 将全部 32 比特用于表示数字,数字是均匀分布的;而由于指数位的存在,浮点数 float 的数值越大,相邻两个数字之间的差值就会趋向越大。

如表 3-2 所示,指数位 E=0 和 E=255 具有特殊含义,用于表示零、无穷大、NaN 等

表 3-2   指数位含义

指数位 E分数位 N=0分数位 N≠0计算公式
0±0次正规数(−1)S×2−126×(0.N)
1,2,…,254正规数正规数(−1)S×2(E−127)×(1.N)
255±∞NaN

值得说明的是,次正规数显著提升了浮点数的精度。最小正正规数为 2−126 ,最小正次正规数为 2−126×2−23 。

双精度 double 也采用类似于 float 的表示方法,在此不做赘述。

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

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

相关文章

重装win11系统后找不到WiFi

由于电脑崩溃重装了系统,win11,装完之后WiFi图标不见了且网络适配器根本没有无线网络选项。 右键电脑》管理》网络适配器。 在刚装好系统时候并没有前两项,查了很多资料,比如 关机14s 重启,还有通过服务配置 WLAN AutoConfig 都…

值得收藏!修复Windows 10/11中找不到输出或输入设备的五种方法

序言 这篇文章主要关注处理声音输出/输入设备未发现的问题。它提供了许多可行的方法,帮助了许多Windows用户。阅读以下内容以找到你的解决方案。 最近,我将Windows 10更新到21H2,发现我的音频无法工作。当我把鼠标放在任务栏上的声音图标(上面有一个十字图标)上时,它会…

word:三线表的绘制【攻略】

word:三线表的绘制【攻略】 前言版权推荐word:三线表的绘制效果简单方法另外的方法 最后 前言 2024-5-7 18:25:08 以下内容源自《【攻略】》 仅供学习交流使用 版权 禁止其他平台发布时删除以下此话 本文首次发布于CSDN平台 作者是CSDN日星月云 博客…

docker jenkins 部署springboot项目

1、创建jenkins容器 1,首先,我们需要创建一个 Jenkins 数据卷,用于存储 Jenkins 的配置信息。可以通过以下命令创建一个数据卷: docker volume create jenkins_data启动 Jenkins 容器并挂载数据卷: docker run -dit…

视频素材库在哪里找免费手机版?8个可以用手机浏览的素材网

在视觉内容占据主导地位的今天,合适的视频素材可以大大提升项目的吸引力和效果。以下列出的视频素材网站为广告制作者、社交媒体策略师及电影制作人提供了从传统到现代风格的各种视频素材选择,满足不同的创作需求。 1. 蛙学府(中国&#xff…

PTQ4SAM、Mamba-Attention、AniTalker、IceFormer、U-DiTs、CogDPM

本文首发于公众号:机器感知 PTQ4SAM、Mamba-Attention、AniTalker、IceFormer、U-DiTs、CogDPM PTQ4SAM: Post-Training Quantization for Segment Anything Segment Anything Model (SAM) has achieved impressive performance in many computer vision tasks. Ho…

【typescript 小秘籍 - 类型自动推导】

今天发现个typescript的小技巧,原来在vscode里面 typescript是可以根据数据,自动推导其类型的,这样就不用自己去手敲定义了。比如 鼠标移动到person上,可以看到 其自动推导了person的类型 然后直接复制下来 直接使用即可。

Redis学习(十)|使用消息队列的重试机制实现 MySQL 和 Redis 的数据一致性

文章目录 介绍原理整体方案实现步骤示例代码总结其他:Kafka 重试策略配置1. 生产者重试策略配置2. 消费者重试策略配置 介绍 在分布式系统中,保持 MySQL 和 Redis 之间的数据一致性是至关重要的。为了确保数据的一致性,我们通常采取先更新数…

【Three.js基础学习】15.scroll-based-animation

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 前言 课程要点 结合html等场景 做滚动动画 1.遇到的问题, 在向下滚动时,下方会显白(部分浏览器) 解决:alpha:true …

什么是多模态大模型,有了大模型,为什么还要多模态大模型?

随着人工智能技术的愈演愈烈,其技术可以说是日新月异,每隔一段时间就会有新的技术和理念被创造出来;而多模态大模型也是其中之一。 什么是多模态 想弄明白什么是多模态大模型,那么首先就要弄明白什么是多模态。 简单来说&#x…

shell常用文件处理命令

1. 解压 1.1 tar 和 gz 文件 如果你有一个 .tar 文件,你可以使用以下命令来解压: tar -xvf your_file.tar在这个命令中,-x 表示解压缩,-v 表示详细输出(可选),-f 后面跟着要解压的文件名。 如果你的 .tar 文件同时被 gzip 压缩了(即 .tar.gz 文件),你可以使用以下…

PHP 匿名函数和闭包在数据结构中的应用

匿名函数和闭包在数据结构处理中的应用php 中的匿名函数和闭包可用于处理数组、链表和队列等数据结构。针对数组,匿名函数可用于过滤元素;针对链表,闭包可用于创建节点;针对队列,匿名函数和闭包可实现 fifo 队列操作。…

2005-2021年全国各地级市生态环境注意力/环保注意力数据(根据政府报告文本词频统计)

2005-2021年全国各地级市生态环境注意力/环保注意力数据(根据政府报告文本词频统计) 2005-2021年全国各地级市生态环境注意力/环保注意力数据(根据政府报告文本词频统计) 1、时间:2005-2021年 2、范围:2…

初始Linux(基础命令)

前言: 我们不能总沉浸在编程语言中,虽然代码能力提升了,但是也只是开胃小菜。我们要朝着更高的方向发展。 最近小编一直在刷力扣,以至于博客更新的比较少。今天就带各位开始学习全新的知识——Linux.至于为啥要学? Lin…

基于FPGA的多路彩灯控制器VHDL代码Quartus仿真

名称:基于FPGA的多路彩灯控制器VHDL代码Quartus仿真(文末获取) 软件:Quartus 语言:VHDL 代码功能: 多路彩灯控制器 综合训练内容要求 设计一台基于FPGA的多路彩灯控制器的设计。要求如下 1.彩灯从左…

IOS自动化—将WDA打包ipa批量安装驱动

前言 CSDN: ios自动化-Xcode、WebDriverAgent环境部署 ios获取原生系统应用的包 如果Mac电脑没有配置好Xcode相关环境,可以参考以上文章。 必要条件 Mac电脑,OS版本在12.4及以上(低于这个版本无法安装Xcode14,装不了Xcode14就…

20230507,LIST容器

学了又忘学了又忘,明知道会忘又不想复习又还得学 LIST容器 1.1 基本概念 链表是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的;链表由一系列结点组成 结点:一个是存储数据元素的数据域&a…

《ESP8266通信指南》12-Lua 固件烧录

往期 《ESP8266通信指南》11-Lua开发环境配置-CSDN博客 《ESP8266通信指南》10-MQTT通信(Arduino开发)-CSDN博客 《ESP8266通信指南》9-TCP通信(Arudino开发)-CSDN博客 《ESP8266通信指南》8-连接WIFI(Arduino开发…

循环链表 -- c语言实现

#pragma once // 带头双向循环链表增删查改实现 #include<stdlib.h> #include<stdio.h> #include<assert.h>typedef int LTDataType;typedef struct ListNode {LTDataType data;struct ListNode* next;struct ListNode* prev; }ListNode;//双链表申请一个新节…

【Python】PTA 查验身份

知识点&#xff1a; 1.这里的加权求和就是指每一位乘以题目给的对应位置上的数字 在python中&#xff0c;对于int(10)这样的转换而来的直接是整数10&#xff0c;但是在c语言中会转换成ASCII值&#xff0c;所以要特别注意 2.本题中有两种情况是错误的&#xff0c;就是要直接输…