几个相同的 0 和 1,既是一个数,也是一条指令:计算机怎么认数与跑程序
如果只让你用手头的 32 个小开关表示一件东西,你会怎么描述它的「大小」?再进一步,要求这同一排开关不仅能表示一个大数,还能在某种读法下变成「把开关 6 里存的两个数加起来,放回开关 3」这样一句话操作,你又会怎么设计?
这不是脑筋急转弯。它正是今天每台手机、每台电脑每天都在做的事:用有限几位的 0 和 1,既算得对,又跑得动你写的程序。这门课的这一讲,就是要回答一个问题:同样的 0 和 1,凭什么既能当数用、又能当指令用,还都能不出错?我们先把「认数」讲清楚,再顺着历史拐一个弯看它怎么变成「跑程序」,最后跟着一条真实指令从头走到尾,把整讲串成一条线。
一、为什么万物都只认 0 和 1?数字到底是怎么「拼」出来的
先问一个最朴素的问题:为什么偏偏是 0 和 1,而不是我们从小就用的 0 到 9?
答案要先回到「数本身是怎么写出来的」。你写的 9472,其实是四个数字各带着自己的权值叠出来的:9 在千位所以值 9000,4 在百位是 400,7 在十位是 70,最后 2 是个位,拼起来才得到九千四百七十二。也就是说,同样的一个符号,安在不同位置上,代表的大小不一样。十进制的「十」根源于我们有十根手指,玛雅人用 20 进制、巴比伦人用 60 进制,时间上用 12 和 60,这些都只是换了套数位记法的选择,不是数学上的天赋特权。
计算机选中这两位的理由很简单:在电路里分辨「有没有电」比分辨「有 0.3 伏、0.5 伏还是 0.9 伏」可靠得多。既然整个世界在机器里都化成了 0 和 1,我们就规定这种记法叫二进制(binary):每一位的权值不是 10 的幂,而是 2 的幂。于是拆分的方法完全照搬十进制,只是把底数从 10 换成 2。比如二进制 1011,就是从右往左读作 $1\times2^0 + 1\times2^1 + 0\times2^2 + 1\times2^3 = 11$。
因为写一长串 0、1 实在太费眼,工程上常用**十六进制(hexadecimal)**作缩写:用 0 到 9 加 A 到 F 表示 0 到 15,每 4 个二进制位正好压缩成一个十六进制位。三种写法同一个数,只不过按约定标注前缀:十进制不带前缀,二进制写作 0b1011,十六进制写作 0xB。课件里那张常用数制表就是这个换算的速查表。
| 十进制 | 二进制 | 十六进制 |
|---|---|---|
| 0 | 0000 | 0 |
| 5 | 0101 | 5 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 15 | 1111 | F |
那一位 0 或 1 到底能表达多大事?很遗憾,单独一位撑不起什么:它只能承诺「红还是不红」这种二选一。把若干位拼在一起,能表示的取值数就按指数涨上去。一般地说,用 base 为 B、n 位去编码,能表示的取值至多有 $B^n$ 种,因为每一位都得从 B 个候选里挑一个。回扣日常的信息量:26 个字母要 5 位($2^5=32$ 够放 26 个),带大小写和标点要凑到 7 位成 ASCII 码;一个 500 人的班给学生发 ID,需要 9 位($2^9=512>500$)。红绿蓝三色只要 2 位就能安排得下 $2^2=4$ 种组合。位数定了,能装的信息就是定死的,这正是后面所有麻烦的起点。
课件这一讲用到的二进制、补码与各类格式,几乎都能在一本经典教材里找到对应章节:Patterson 与 Hennessy 合著的 Computer Organization and Design: RISC-V Edition(第 2 版,2020)把「有符号无符号数」放在第 2 章、IEEE 754 放在第 3 章的浮点一节、处理器数据通路放在第 4 章、内存层次放在第 5 章。P&H RISC-V
先记住这个地基:进制只是换底数的记法,而机器的加工工厂只建在 0/1 两进制上。接下来要面对一个棘手的现实正好从这里长出来:位数一固定,负数放哪儿、小数放哪儿?下一节先看最简单的整数。
二、负数怎么表示才不捣乱?符号位直接抄近路,为什么输给了补码
无符号整数:天然友好,但没地方写「负号」
把若干位直接当非负整数读,是最自然不过的表法。4 位来看,0b100 就是 4。n 位无符号整数的范围是 0 到 $2^n-1$,全部码位都用来装大小了。它唯一的软肋是没有负号,一碰到减法、温度、欠款这类带方向的量就束手无策。所以我们得专门给「有符号整数」另想办法。
直觉上最省事的做法,是干脆挪出最高的一位当符号位:这一位叫 MSB(最高有效位,Most Significant Bit),1 表示负、0 表示正,剩下的位照旧读大小。这就是**符号与数值(Sign & Magnitude)**表示。听着很顺,可它埋了两个雷。第一个是浪费:既然最高位只管正负,按同一位串去读,就会同时冒出 +0 和 -0 两个零。第二个更要命:两数相加时,硬件没法直接把位串加起来完事,必须先比符号、再按同号还是异号分情况处理,等于给加法器加了一套额外规则。
二进制补码:用一点聪明的浪费,换一个不啰嗦的加法器
现代所有硬件清一色用的是二进制补码(two's complement)。它怎么定义负数的?一句话:取相反数 = 按位取反再加一。+7 是 0b 0000 0111,把它每一位翻过来得 1111 1000,再加一得到 0b 1111 1001,这就是 -7。想验证也很简单:把 +7 和 -7 两串直接加在一起,你会得到 0b 1 0000 0000,溢出丢掉进位后正好回到 0,所以这确实是互为相反数。
补码的好处要回到 MSB 上看。最高位仍在兼任符号,但它不再像符号与数值那样需要单独的规则:同一套加法器,把正数减负数当普通二进制加法直接算就行,符号位不用特殊对待。为什么能这样?因为补码有一个近乎偷懒的编码设计,把码位「绕成了一个环」。看下面这张课件里的旋转轮盘:

图注:课件补码「旋转式编码」轮盘(课件原图)。补码把数安排成一个环:正整数排满半圈,加一跨过最大值后就直接绕回另一头的负数区。所以同一套加法器对正负一视同仁,减一个数等于加它的相反数。
顺着这张图体会旋转的含义:在正数最大值那里再加一,不报错也不进位停下,而是顺着环绕到最负的那端去。正是这种「绕圈」消除了 +0 与 -0 的重复:那个被符号与数值浪费掉的 -0,在补码里恰好被用作最小负数 $-2^{n-1}$,于是补码的负数比正数多一个,还白赚了一块能精确表达的范围。课件给出一个直观例子:8 位里 +7 与 -7 分别是 0000 0111 与 1111 1001,两者相加直接归零。
把位宽放宽到真实硬件,RV32I 的整数寄存器是 32 位的,补码能表示的范围就是 $-2^{31}$ 到 $2^{31}-1$,其中寄存器 x0 硬接成恒零,写进去会被直接丢弃,往往可以当「常数 0」来用。RISC-V spec
一句话收束:符号与数值把规则做了一半,补码则用少掉一个编码位的小小浪费,换来了一台对正负一视同仁、减法自动退化成加法的加法器。硬件怕的就是两套规则,这正是补码胜出的原因。
三、装不下的数和零点几:溢出与 IEEE 754 拆解同一件事
先立一道墙:溢出
补码解决的是「放得下」时的算术;可一旦结果放不下,麻烦就来了。**溢出(overflow)**指的是:算术运算的数学结果无法用被固定的硬件位数表示。课件给了两个例子:无符号那串全 1 的 0b1…1 再加 1,数学上应该变成 $2^n$,可硬件只留了 n 位,一进位就被丢弃,结果悄悄绕回 0b0…0 也就是 0,数学上完全不对;同理补码最大正数 0b01…1 加 1 会翻成最高位为 1 的 0b10…0,那在补码读来是 $-2^{n-1}$ 而非 $+2^{n-1}$。
先记住这道墙:位数固定,结果一旦越界就出错且常常是很隐蔽地错。整数尚且如此,遇上想要极大又极小的数,比如光速这种跨度,直接把小数按位存是存不下的,必须换一种玩法。
IEEE 754:把数拆成 符号 × 尾数 × 2^指数
科学计数法早已教会我们一招:别把一个数平铺着写,把它拆成「大小在 1 到 2 之间的尾数」去乘上 2 的若干次方。IEEE 754 单精度(一个 float,实际叫 binary32)就是把这一招落到了固定的 32 位上:这 32 位被切成三段,当头 1 位表正负符号,中间 8 位存指数,最后 23 位存尾数。IEEE 754-2019

图注:IEEE 754 单精度一个 float 的内存布局(Wikimedia Commons,CC BY 3.0):32 位从左到右分成 1 位符号 sign、8 位指数 exponent、23 位尾数 fraction,图示样本读出为 0.15625。它示意的是字段切分与命名,图中未标 bias/隐藏位。
顺着这个套路还有三个「为什么」要补,这三处课件没展开,却是把设计动机讲透的关键,Goldberg 在经典教程 What Every Computer Scientist Should Know About Floating-Point Arithmetic(ACM Computing Surveys, 1991)里讲得最清楚:
为什么指数要偏置? 指数可正可负,IEEE 不用符号位也不用补码存它,而是给它加一个固定偏移 bias=127,把「读出的同位数的无符号指数」减 127 才是真指数。好处是 8 位无符号指数 0 到 255 全都能被平铺使用,不必为负数发愁。
为什么尾数最左那一位不占位? 规格化浮点数的尾数总在 1 到 2 之间,最高那位恒为 1。既然恒为 1,就没理由花钱存它,这一位被当作**隐藏位(hidden bit)**省掉,于是文件里只存 23 位、实际语义上是 24 位的精度。
为什么默认「最近取偶」舍入? 两个数的真实结果往往落在两个可表示浮点正中间,那到底舍向哪头?IEEE 默认的是 rounded-to-nearest-even:恰逢中点时,让保留下来的最低位取偶数。这样做的深层理由是避免「每次都朝同一方向舍、误差单向累积漂移」这类系统性偏差。Goldberg
课件拿光速来演示这读法:c 写成二进制规格化是 $1.0001\dots\times2^{28}$,符号位 0,指数 28 加偏置 127 得 155(二进制 1001 1011),尾数只存去掉首位 1 的后 23 位。特殊的情形(正负 0、正负无穷、NaN 这类非数、以及 0 与最小规格化数之间的 subnormal 渐变下溢)也都有约定好的编码,这里按下不表,只需知道一个数并不是非黑即白:它还可以是「无限大」「不是数」和「接近零的小尾巴」。
bfloat16:给机器学习砍尾数、保指数
FP32 已经是 32 位了,可人工智能训练的显存吃紧,工程师想要更省的 16 位。问题是拿哪个 16 位法?IEEE 正式的 binary16(FP16)只有 5 位指数,范围窄到需要额外的 loss scaling 才能训练稳。于是有人反其道而行:保留 FP32 那完整的 8 位指数,只把 23 位尾数砍到 7 位,凑成 1+8+7 就是 bfloat16(brain floating point)。因为指数位一个没少,bfloat16 的数值范围跟 FP32 几乎完全一致,训练时连超参都不用调。从 FP32 转成 bfloat16 也简单:截掉低 16 位尾数,再按最近取偶舍入即可;而把 BF16 数据加宽回 FP32(比如在累加、更新权重之前)时,只需把低位缺失的尾数补零。bfloat16
课件那张 bfloat16 位结构图,正是拿来和单精度对照着看的:

图注:课件 bfloat16 位结构图(课件原图)。格式用 16 位,1/8/7 三段排布,其中 8 位指数与 FP32 的指数位完全一致,被视作 32 位 IEEE 单精度的缩短版,用于加速机器学习。
它在实际训练里怎么用?并非全链路都降成 16 位,而是张量数据的存取用 BF16、累加和权重更新仍留在 FP32——下面这张论文里的混合精度数据流阐明了这种分工。

图注:Kalamkar 等论文 Figure 1 的混合精度数据流:神经网络各层的张量以 BF16 传输与存取,图中的「Q」转换器负责 BF16 与 FP32 间的换算,而偏置与权重更新始终用 FP32 保精度。bfloat16
到这里,「数字怎么表示才算得对」的问题画上了句号:位数一固定,整数和小数是同一场赌局,要么像补码那样把冗余让给单一符号语义,要么像 IEEE 754 那样把位数切成符号、指数、尾数去换一个几乎能盖住宇宙尺度的动态范围。可电脑里除了数字还有别的——我们写下的「程序」是怎么被记住、被读起来的?这要等一个历史性的观念突破。
四、程序也是一段放进内存的数字:存储程序如何催生三大件
ENIAC 的困境:想换问题,先插两天线
换个角度问:如果把一串 0 和 1 存进内存,它能表示的不止数字,还可能是「要机器做的事」吗?这听起来疯狂,却是计算机史上最关键的转向。早期的电子计算机并不这么想。1946 年公开的 ENIAC(宾夕法尼亚大学)算得极快,课件口径是 10 位数乘 10 位数只要约 2.8 毫秒,但它的「程序」靠接线板和开关拼出来,每换一个新问题往往要重新配线,达到「很多天」的量级(课件写的是 2 到 3 天,权威档案只佐证到多天量级,此处保留课件口径)。机器再快,编程的人却被焊死在插线台上。
存储程序:程序也是能住的居民
让程序真正住进内存的,是所谓**存储程序(stored-program)**概念:程序不必以单独的电线形式存在,它像数据一样,被写成 0 和 1 放进内存;于是重新编程 = 重写内存,而不是重接线路。EDVAC
这个概念的最早书面勾勒,出现在 1945 年 6 月 30 日 von Neumann 署名的《EDVAC 报告第一稿》里。需要说明的是,von Neumann 是这份报告的作者与传播者,其思想源自当时宾大 Moore School 团队(Eckert、Mauchly 等人)的讨论语境,把功劳单独记在他一个人头上并不公允。准确的说法是:这份报告把「指令与数据同存于同一台可互换存储器、由中央控制按序取出执行」的思想最早写成了书面文字并广泛流传,而「冯·诺依曼架构」「存储程序」这两个名字反而是后人贴上去的标签。它和今天 CPU 的关系只看这张课件框图就清楚了:

图注:课件冯·诺依曼架构框图(课件原图)。中心是内存,指令与数据同挂在一条总线上、由同一个内存控制器读出;处理器(CPU)从中取指令、再取它要加工的数据,两者共用同一个地址空间。
同一个数,两种读法
存储程序的奇妙后果,在于「一个内存里的数到底是数值还是指令,完全看你拿什么来解释它」。课件举的例子是最佳示范:同一串 0x007302B3,把它当十进制大数读是 7,537,331;可把它当一种约定语言(指令集)来解释,它又是一条 RISC-V 指令 add x5, x6, x7(把寄存器 x6 和 x7 的数字加起来,存进 x5)。一个数同时是数值和操作,处理器看它是什么、它就照着哪个角色执行。
顺着这个「谁来解释」的问题,三大件的分工图就出来了。计算机可以抽象成三样相互咬合的东西:
这张工厂图是这一讲反复复用的骨架:处理器是负责动手干活的车间与下指令的生产计划,内存是堆原料和半成品的库房,**输入输出(I/O)**是跟外界交接货物的口岸。内存里躺着的那串 0 和 1 自己不会说话,是处理器拿它当指令还是当数值用,才决定了它的身份。要彻底听懂一台程序计算机,这一步是关键:先接受「内存里的都是没被解释的 0/1」这一事实。
五、想又快又便宜,就得把记的东西分几层放:内存层次与拖到 I/O 的磁盘
速度、容量、价位:一个三角里只能抓到两样
理解了「统一存储」的架构之后,新的矛盾冒出来:这台内存又大又快又便宜,现实中并不存在。快、大、便宜是三个相互打架的指标,速度上去,单位容量价格就跟着涨、容量还得往下降。怎么办?答案是把存储做成一个层次,而不是一块。
这个层次非常像你用一个书架:你把最常用的几本书放在手边桌面上,次常用的放书桌抽屉,很少翻的挪到高层书架顶。因为每次动作都从手边开始找,绝大多数时候命中极快,只有找不到时才去更外层翻。处理器这边的对应物就是——寄存器(手边)、缓存(桌面)、主存(抽屉)、磁盘(远处书架)这么一层层铺开。缓存(cache)正是靠「把最常命中的数据放到更快一格」生效,读者体验到的是「几乎和最快的一样快、几乎和最大的一样大」的错觉。它并不真的都装得下,它只是让常用的都在手边。下方的课件层次图把这条从快到慢的排布钉死:

图注:课件内存层次结构图(课件原图)。存储被排成由快到慢、由贵到便宜的金字塔阶梯:寄存器、缓存、主存往下再到磁盘;越靠上越快越贵越小,越靠下越慢越便宜越大。
主存为何会「失忆」:RAM 与 ROM
层级内部还要分「失忆」与「不失忆」。主存里最主流的是 RAM(随机存取存储器,Random Access Memory),它分更快的 SRAM 与更省的 DRAM 两亲兄弟,共同点是易失:一断电,里面存的所有东西当场作废。你现在在跑的软件,恰恰就放在这种一关机就丢的 RAM 里,所以开机后要重新从别处把它们请回来。而 ROM(只读存储器)那一族(从生产时就固化内容的 MROM 到可擦写的 EPROM/EEPROM)是非易失的,断电也能留住,适合装开机自启的固件。区分「易失/非易失」永远是理解主存的第一件事。
磁盘是 I/O,不是内存
顺着层次最慢的那一层往下,就容易出一个概念性混淆:硬盘仓库算不算「内存」?课件的判断非常锋利:磁盘不是内存,磁盘是挂在 I/O 上的设备。理由有三:它不按内存那种按地址随机访问的粒度来读写,而按一个个数据块访问;它是块设备、经 I/O 通道进出;甚至极端些,当你需要的一切都在 RAM 里时,电脑拔掉磁盘也能开起来跑。它是断电也能留数据的非易失大仓库,跟易失去电的主存不是一个物种,只是常和主存并排出现在同一张层次图里,容易让你默认它俩同类。
那仓库本体又有两种物理实现。**机械硬盘(HDD)**靠磁化高速旋转盘片上的磁性材料存数,读到它要等盘片转到位、磁头移动到位,所以访问慢(课件 2010s 口径约 12ms 量级);还怕振动引起磁头撞上盘面的「磁头碰撞」,也怕文件碎片化。**固态硬盘(SSD)**没有机械运动,靠把电荷困在 NAND 闪存的半导体单元里表示 0 和 1,比 HDD 快得多、也更省电,这是今天手机和笔记本的主流。
NAND 的核心玩法在「一个单元存几位」。闪存厂商 KIOXIA 用一篇很直白的科普把这件事讲清了:早期一个存储单元只能存两个电荷态,即 1 bit,称作 SLC;后来能在同一单元塞下 4 个电荷态,就让每单元存 2 bit(MLC),容量不换尺寸就翻倍;再往后是 8 态 3 bit 的 TLC、16 态 4 bit 的 QLC。可天下没有白来的密度:每单元塞的位数越多,写/擦耐久越低、读写越慢、对纠错的要求越高。KIOXIA
你有没有发现这套「塞得越多越容易错」的取舍,和上一节 bfloat16 砍尾数换范围其实是一模一样的主张?两个话题共享同一个母题:有限资源里,密度与鲁棒性是此消彼长的两面。
课件那张 HDD vs SSD 的对比表把两边的差异系统整理了出来,但它标的价格与容量是 2010s 口径。真正能回答“该选谁”的结论,是用有日期的动态数据补上去的:Backblaze 这家云厂商公开自己真实硬盘采购记录,每 GB 价格从 2009 年约 $0.114 一路降到 2022 年 11 月约 $0.014,累计降了约 87%(统计截至 2022 年 11 月,不等于今天的行情,2025-2026 受 AI 需求影响 SSD 相对 HDD 价差还在拉大)。Backblaze 成本
而在可靠性与寿命上,也别再拘泥于「一块盘用 5 到 10 年」这种精确寿命的说法:Backblaze 2026 年第一季度在其管理的数据中心里监控了约 34 万块 HDD,季度年化故障率约 1.24%、累计终身约 1.39%。更值得记住的是它那句方法论提醒:某些型号一年坏一块就会把故障率顶得很高,看故障率要看大盘趋势,别盯着单一型号的小样本下结论。Backblaze 可靠性
所以存储是一整个用速度、容量、价位层层兑换出来的梯度,「磁盘是不是内存」是这个梯度上最锋利的一道边界。想要把整个工厂讲完,还差最后一环:处理器到底是怎么读那一排 0 和 1 的?
六、处理器在干嘛:跟着 addi 把一条指令切字段、译码、执行走完
指令是软件和硬件的约定语言
回忆第 4 章那个谜题:0x007302B3 既能当数字读,又能译成 add x5, x6, x7。究竟靠什么把它读成一条操作?答案是:把 32 位按一张写死的合同切成若干字段(fields),每个字段看各自那几位。RISC-V 按这个切法有一套固定格式,最常用的寄存器相加是 R 型:最高 7 位 funct7、接着 5 位 rs2、5 位 rs1、3 位 funct3、5 位目标 rd、最低 7 位 opcode。funct7 与 funct3 一起点明「做什么运算」,rs1、rs2 是去取哪两个源寄存器的数,rd 是结果写回哪个目标寄存器。PDF 里的 0x007302B3 填进这些格子,就读出 rs1=x6、rs2=x7、rd=x5、操作是 add。
R 型之外还有五个兄弟格式。下面这是 RISC-V 官方的六格式合成图,它把「同一个 32 位怎么为不同用途重排立即数」一目了然地摊开:

图注:RISC-V 官方基础指令六格式(R/I/S/B/U/J)纵向排列(RISC-V Unprivileged 规范 v20260120)。每一行都把 32 位画成字段框,标出 funct7/rs2/rs1/funct3/rd/opcode 或 imm 立即数的比特位置;opcode 恒定占最低 7 位,其余字段按格式挪动。RISC-V spec
如果你只是想让处理器算一个数和一个立即数,就不用两个寄存器了,改走 I 型(如 addi rd, rs1, imm),把一个 12 位立即数填进原属 rs2 的位置。这就是为什么同一串 0 和 1 的宽度永远是 32 位,却能承担好多不同形状的操作——它只是换着法子安排那几个格子的用途,而 x0 到 x31 的 32 个寄存器(x0 恒零)是所有算式的共同原料。
处理器基本组成:谁在干活、谁在派活
处理器干这件事需要几个零件配合:PC(Program Counter,程序计数器/指令指针),指着下一条要执行的指令藏在内存哪个地址;寄存器,一小组极快、可寻址的小存储;译码器,把 PC 指来的那串 0/1 拆出「做什么、用哪些数」;功能单元,实际动手算的 ALU(算术逻辑单元)等。第 4 章的工厂框架在这里精确对位——数据通路就是车间里那排机床,负责干活的硬件;控制就是生产计划与质检,负责决定每台机床这步该做什么、先后顺序如何。P&H RISC-V
一条指令的旅程:addi t0, x0, 6
把抽象的词一个接一个落到真例子上,不如直接跟着一条真实指令跑一遍全程。就拿课件里那条 addi t0, x0, 6 当发动机:t0 是寄存器 x5 的助记名,x0 恒为 0,所以这句的意思就是「把寄存器 x0 里的 0 加上立即数 6,写进寄存器 t0」,最终 t0 里出现 6。处理器按五个固定步骤走完这条指令:
课件把这五步画成了一幅执行流程图:

图注:课件「指令执行」五步流程图(课件原图):PC 送地址给内存,内存回指令给译码器,译码器识别源/目标寄存器与操作,功能单元接收寄存器输入执行,最后把结果写回寄存器或内存。图中正是 addi 这条指令依次穿过各部件的情形。
走完你会发现,这一讲前面反复出场过的每个名词——补码、bit 位宽、寄存器、主存、译码器、ALU、输出为 0/1 的字段——在这五个鼓点里全都找到了自己的位置。你写在源代码里的一段程序,编译后变成一行行这样的 32 位数字,硬件就按固定的机器周期、一个接一个地这样切字段、译码、执行。同一个 0x007302B3 既能是数字 7,537,331、又能是加两条寄存器的 add,计算机世界的一切差异,都来自对同一串 0 和 1 的不同解释,与不同硬件的安排。
到这里,这一讲最锋利的那条主线就合上了:开头你看到 0 和 1 被当成数来算得对,后来看到同样的 0 和 1 被当成指令来跑程序。所谓计算机组成原理,讲到底就是管理这批 0/1 的解释权——你给它一个算术地址,它给你一个数;你给它一套字段约定的读法,它还你一步操作。现在再看题目那句「几个相同的 0 和 1,既是一个数,也是一条指令」,应该有底气了:不是它们神秘,而是人类约定了两套读法,硬件在同一串比特上各取所需。
参考文献
本专题引用的核心资料如下,建议深入学习时阅读原文:
- Computer Organization and Design: RISC-V Edition(第 2 版) — Patterson & Hennessy,Elsevier 书目页
- IEEE 754-2019 Floating-Point Arithmetic(现行版本记录) — IEEE SA 官方标准检索页
- What Every Computer Scientist Should Know About Floating-Point Arithmetic — David Goldberg, ACM Computing Surveys 1991,Oracle 免费重印
- A Study of BFLOAT16 for Deep Learning Training — Kalamkar et al., arXiv:1905.12322
- First Draft of a Report on the EDVAC — John von Neumann, 1945-06-30,MIT STS.035 馆藏 PDF
- The RISC-V Instruction Set Manual, Vol. I: Unprivileged Architecture (v20260120) — RISC-V 官方规范
- NAND Flash: The Alphabet Soup, From SLC to QLC — KIOXIA 官方博客, 2025-01-22,原文
- Hard Drive Cost per Gigabyte over Time — Backblaze(Andy Klein),博客原文
- Backblaze Drive Stats for Q1 2026 — Backblaze(Stephanie Doyle),季度报告