首页 > 其他分享 >CSAPP 01:信息的表示

CSAPP 01:信息的表示

时间:2025-01-23 21:42:38浏览次数:1  
标签:编码 CSAPP 01 进制 二进制 信息 times 序列 我们

Intro

本文中数字的右下角标识代表该数字所使用的进制

计算机里的数据是什么?

首先要明确一点,计算机中几乎所有的信息,在实际上都是电信号。
这引申出了计算机所能控制的信息的最小单位——bit。
bit就是binary digit,当然计算机里的信息不是一串0和1,而是高电平与低电平,它们被表示为0和1。
这也就是说,下文所提到的所有的二进制数序列,在事实上是储存在计算机的储存元件中的一系列由高低电平组成的电信号序列。它们不是一个数,而是一系列的电信号。

高低电平事实上是一个范围,而非一个定值,这给了整个电路容忍噪声的能力。
选择了更高进制的计算机(如三进制)能在一个bit内表示更多的信息,但增加新的状态将不可避免的带来硬件成本的上升,选择成本还是信息量,是现实需要考虑的问题。
从数学的角度出发,事实上选择何种进制并无影响,数值并不会因为进制不同而变得不同。

于是我们现在知道了,计算机里的信号,都可以被表示为一系列的0和1。
更进一步,我们将n个bit组合成一串有序的数字串,我们就可以用这样的数字串去表示几乎所有的符号。

譬如ASCII。
我们使用8个bit来表示一个ASCII符号A

0100 0001 -> A

像这样将字符映射到二进制格式的过程就是编码。
而这样的一个8bit的序列,我们就称它是1byte,也就是一字节。

ASCII一共只有127个符号,只使用7bit就能完成编码,为什么要用8bit来编码?或者说,为什么1byte=8bit?
这其实是一个马屁股决定火箭直径的问题
事实上,在字节长度未被确定时,是有各种字节的长度不同的机器的。1byte = 5bit、6bit、7bit的机器一样是存在的。但或许是由于IBM System/360的成功,它所使用的1byte = 8bit被广泛接受,成为了标准。

字节是计算机储存与处理信息的基本单位。

进制互换

二进制数序列是计算机所能直接使用的,但一个过长的二进制数序列对于人类来说是难以识别的,因此,我们不得不引入识别负荷更小的记录方式。

在这里,我们姑且将二进制数序列看作是一个二进制数字,以方便进行进制的转换。

进制是进位计数制的意思,X进制就是指计数到X时就进一位。

以我们最常用的十进制来举例,当我们从零开始数,数到十的时候就往前进一位。由于我们最常用的进制就是十进制,这使得我们几乎认为一个数值的十进制表示就是这个数值本身。
上文中已经提到了,一个数值不因为其表达形式的改变而改变,所以接下来要注意,所有的转换,事实上只是同一个数值的不同表达形式。

由此我们来理解二进制。
以数字\(42\)来举例:
它的十进制表达是: \(42_{10} = (4 \times 10^1 + 2 \times 10^0)_{10}\)
它的二进制表达是: \(10 1010_{2} = (1 \times 2^5 + 0 \times 2^4 + 1 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 0 \times 2^0)_{10}\)

你可以发现,对于一个有\(m\)位的\(n\)进制数字,它的十进制表达事实上就是它的第\(i(i \in [1,m])\)位上的数字\(x_i\)去乘\(n^{i-1}\)的累加。即:

\[\sum_{i=1}^{m} x_i \times n^{i-1} \]

于是现在,你学会了将一个任意进制的数字转化为十进制表达。
同样的,你只需要将这个过程逆过来,就能将任意一个十进制数字转化为任意进制的表达。

让我们回到本部分开头所述的问题:一种识别负荷更小的二进制数序列记录方法——十六进制。
十六进制是计数到十六(十进制表达下)时就进一位。
即:\(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10\)。
我们在上面已经知道,二进制数序列可以编码任意符号,当让也包括这十六个符号。
\(16 = 2^4\),这意味着这些符号只需要四位的二进制数序列就能完全编码。
于是,我们将0000编码为十六进制的00001编码为十六进制的1,依此类推,将十六个符号全部编码成四位的二进制数序列。这样,我们就得到了一个十六进制符号对应四位二进制数序列的映射表。
接下来就可以简易地表达一个长的二进制数序列了。我们将一个二进制数序列从最左边起,每四位做一个分割,将一个二进制数序列分割为多个四位长度的二进制数,如果最后一个不足四位就在它的右边补零。之后,我们将每一个四位二进制数序列按照刚刚得到的映射表写成十六位符号,于是,我们就将一个长二进制数序列改写成了一个短的十六进制数序列。
还是以42举例:
它的二进制数序列表达为101010,可以写作0010 1010,即2 A

八进制也是同理的,不过由于\(8 = 2^3\),所以它仅需要三位二进制数序列就能完成编码。
它对101010的分割是101 010,也就是5 2

值得注意的是,这种方法对于数值来说同样是成立的,也就是说,对于一个二进制数,同样可以用这种方法来进行进制转换。

整数

我们已经知道了,我们所见到的数值,对于计算机来说事实上只是一串电信号。
但我们也知道计算机是可以进行计算的,而且计算能力很强,这意味着,没有智能并不代表你不能完成计算。

事实上,我们并非没有数值,我们可以用二进制数序列来编码数值。
只要我们将一个二进制数序列视作是一个二进制数,这个序列就能表达一个具体的数值。

于是我们有了无符号整数。它能表达的数字范围是\([0,2^{n}-1]\),\(n\)为编码该整数所使用的二进制序列长度。
同样的我们可以为它加上符号,我们将编码这个整数所使用的二进制序列的最左边那一位定义为\(-2^n\),这样,他能表达的数字范围就变成了\([-2^n,2^{n-1}-1]\)。
这种表达数字的方法便是补码。

事实上,有符号整数还有不同的表达方法,例如反码与原码,但它们都会引入\(\plusmn 0\)的问题。

我们现在知道了如何编码一个整数,那么这个编码的二进制数序列长度\(n\)应该是多少呢?
这与具体机器上不同语言的具体实现有关,但这个数值一般是\(8^n\),这是因为一个字节能表示八位的二进制数序列,而将这个数值设置成不同的字节将有利于储存与使用。

浮点

我们已经知道了使用一个二进制数序列可以简单准确地表示一个整数,但当这个问题扩展到小数时,一切就都变得复杂了起来。

根据上面我们已经知道,一个\(n\)进制的整数,它的数值可以用累加的方法求出,事实上,小数也是可以的。

我们将刚刚的公式稍作改写,对于任意一个数:

\[(x_m...x_1x_0.x_{-1}x_{-2}...x_{-n})_k \]

它的值表达为十进制形式可以用如下公式求出:

\[\sum_{i={-n}}^{i={m}} x_i \times k^{i} \]

这样,我们就表示出了任意进制下的小数。
那为什么说问题变得复杂了呢?
例如使用十进制小数无法在有限长度的编码内准确表示\(\frac{1}{3}\),不同进制下的小数表达出来的事实上是一个\(\frac{x}{k^n}(x,k,n \in N^+)\)它的分母是被固定的,这导致我们在有限长度编码下只能准确的表示出能被写为\(x_i \times k^i\)的数字,而其他的数字只能近似地去表示。

这也就是为什么常能听到浮点数是不准确的的说法。

IEEE 754

IEEE 754提供了一种简单地表示一个极大/极小的浮点数的方法。
事实上就是一种二进制下的科学计数法。

我们以\(2.5\)为例:
它的二进制表达是\(10.1\),那么将它写成二进制下的科学计数法就是\(1.01 \times (2^1)_{10}\)

如何将这个数字用二进制序数列编码出来?
IEEE使用4byte/8byte来表示一个单精度/双精度的浮点数。
它将它分为三个字段,分别是:

4byte:[31->s][30:23->exp][22:0->frac]
8byte:[63->s][62:52->exp][51:0->frac]

其中数字代表该字段开头及结尾的地址;s是符号位,exp是阶码,frac是小数字段。
怎么使用这三个字段来表示一个小数?
首先我们将一个二进制小数写为以下式子的形式:

\[(-1)^s \times M \times (2^E)_{10} \]

s作为符号位,直接等效于式子中的s,即1是负、0是正。
exp是阶码,它是一个以偏置形式表示的无符号整数,与\(E\)的关系是:\(exp = E + bias\),这里的\(bias\)是偏置量,它等于\((2^{n-1})_{10}\)这里的\(n\)是字段exp的位数。使用这种表述形式是方便负指数的表达。
frac是表达的数字的小数的部分,在科学计数法中,小数点前有且仅有非零的一位数,在二进制中这个数只能是\(1\),故可以省略。它直接编码\(M\)的小数部分,如果位数不足则在最后补零。
这样,我们就能表达一个规格化的值的浮点数了。

让我们看回刚刚的\(2.5\),我们先将它写成\((-1)^0 \times 1.01 \times (2^{1})_{10}\)
于是我们就能将它编码为单浮点0|100 0000 0|010 0000 0000 0000 0000 0000这里用|分隔开的就是对应的三个字段。

上面我们注意到,我说这个数是一个规格化的值。那么什么是规格化的值?
事实上,这种浮点数的表示一共有三种情况,由expfrac来决定处于何种情况。

  1. exp既不为全0,也不为全1时,我们认为它是一个规格化的值。
  2. exp全为0的时候,我们就认为这个值是一个非规格化的值
  3. exp全为1的时候,我们认为它是一个特殊值。此时,若frac0,我们认为它是无穷大;若frac不为0,我们则认为它不是一个数,即NaN

为什么要这样做?

例如,假设我想要表示\(0\),我们会发现,\(0\)无法写成科学计数法的形式,因为此时的\(E\)无法确定。
在一个非规格化的值的浮点数表示中,\(E = 1 - bias\)。此时我们已经不认为这个数是一个科学计数法表示的数字了,即我们不再认为这个数隐含一个小数点前为1的前提。
也就是说,这个时候我们认为\(M \in \left[ 0,1 \right)\)。当然frac仍旧表示\(M\)的尾数部分。你可以简单的看作规格化数前隐含的1变成了0
于是我们就能表示0,以及距离0非常近的数字了。
当然我们发现这些更改与符号位s无关,也就是说,存在\(\plusmn 0\)。

当我们从零开始数exp全为1的时候,这个浮点数就应该被解释为一个特殊的值了,它们被用于处理一些溢出或是无法计算的数值。

Outro

于是,我们顺利地将计算机所能识别的电信号转化成了人类所能识别的数据。
下一章我们便可以开始处理这些数据了。

标签:编码,CSAPP,01,进制,二进制,信息,times,序列,我们
From: https://www.cnblogs.com/TashiKani/p/18688665

相关文章

  • 「NOI2018」情报中心
    考虑令\(f(i)=\text{dist}(u_i,v_i)-2w_i\),那么一种方案\((u_i,v_i,w_i)\)和\((u_j,v_j,w_j)\)的贡献(钦定相交部分一边都是\(u\),一边都是\(v\))的两倍就是\(f(i)+f(j)+\text{dist}(u_i,u_j)+\text{dist}(v_i,v_j)\)。枚举\(t=\text{LCA}(u_i,u_j)\),那么即是:\[f(i)+f(j)+d......
  • day01practice
    课堂回顾day01,首先讲解了Java的背景,Java的安装和环境变量的配置,随后在记事本内编写了第一个HelloWorld程序,认识了class文件和java文件,然后安装IDEA开发工具,并启用通义灵码ai辅助编程和学习,idea的基本设置和快捷键操作,最后教学到java的基础语法。我们分别从main入口,功能单元方法,注......
  • 题解:洛谷 P1025 [NOIP2001 提高组] 数的划分
    题目https://www.luogu.com.cn/problem/P1025解法1:深度优先搜素准确来说是DFS+最优性剪枝。我们在上一次选择的数字之后的范围进行枚举,记录这次选择的结果。优化:记录之前的选择的数字之和,我们记为 ,那么枚举的范围为 。 记录的是选择的数字。如果顺利地枚举完了每一......
  • 爬取NBA球员信息并可视化小白入门
    网址:虎扑体育-NBA球员得分数据排行第1页步骤:分析页面确定URL地址模拟浏览器向服务器发送请求数据解析提取想要的数据保存数据爬虫所需要的模块requests(发送HTTP请求)parsel(解析HTML内容)pandas(数据保存模块)第一步分析页面--确定是静态页面还是动态页面右......
  • Markdown学习day01
    Markdown语法学习标题:用#加Enter键:#+标题,有几个#就是几级标题#+空格+标题##+空格+标题###+空格+标题####+空格+标题#####+空格+标题字体粗体,两边加**;字体斜体,两边加*;字体斜体加粗,两边加***;字体删除线,两边加~~;字体引用使用>+空格引用分割线1.使用---2.使......
  • SSM餐厅订餐系统 SSM架构下的餐厅点餐与信息管理平台 基于SSM框架的餐厅在线订餐管理
    XXX标题 (配套有源码程序mysql数据库论文)本套源码可以先看具体功能演示视频领取,文末有联xi可分享随着互联网技术的飞速发展,餐饮行业的信息化管理成为提升运营效率和用户体验的关键。传统的餐厅订餐方式往往依赖于人工记录和电话沟通,这种方式不仅效率低下,还容易出现信息错......
  • SSM财务报账管理系统 SSM架构下的财务报销信息化平台设计 基于SSM框架的企业财务报销
    XXX标题 (配套有源码程序mysql数据库论文)本套源码可以先看具体功能演示视频领取,文末有联xi可分享随着企业规模的不断扩大和财务管理的日益复杂,传统的财务报账方式已经难以满足现代企业管理的需求。手工处理报账信息不仅效率低下,还容易出现错误和信息丢失的问题。此外,随着......
  • 批量登录灯塔扫描的信息收集GUI工具-TDGO更新(v1.0.1)发布
    GitHub:https://github.com/lxflxfcl/DTGO作者语:嘘,我正在狠狠鞭打你的灯塔前言上一篇文章发布的DTGO的初始版本TDGO(灯塔狩猎者)—一款分布式灯塔信息收集工具现在更新了一版,更新内容如下:功能更新:主界面UI美化【由Super师傅完成】删除任务记录【删除记录时会同时删......
  • TDGO(灯塔狩猎者)—一款分布式灯塔信息收集工具
    GitHub:https://github.com/lxflxfcl/DTGO作者语:嘘,我正在狠狠鞭打你的灯塔DTGO(灯塔收割者)是一个用于批量管理和监控资产灯塔系统任务的图形化工具。它能够自动发现灯塔系统、批量提交任务、监控任务状态,并支持导出任务结果。功能特点灯塔发现自动调用FOFAAPI发......
  • 011. 带分数
    011.带分数原题链接:P8599[蓝桥杯2013省B]带分数解题思路:题目大意:给你一个\(n\),问有多少种表示为\(a+\fracbc\)的形式,且\(a\),\(b\),\(c\)中的数字正好不重复不遗漏的包含数字\(1\)~\(9\)。分析:如果这道题去枚举\(a\),再去一个一个枚举\(b\),再算出\(c......