CMU 15-213 CSAPP:从内存到浮点数的那些坑(Data)

发布时间:2026/9/14 12:36:02

CMU 15-213 CSAPP:从内存到浮点数的那些坑(Data) 这是一篇系统级编程CS:APP / 深入理解计算机系统的学习笔记。在重新翻阅这篇笔记时我把曾经课堂上“戛然而止”的思维片段进行了补全。如果你也对 C/C 底层、内存布局、二进制的那些“玄学”Bug 感兴趣希望这篇笔记能帮到你。Lec 01 Course ReviewMemory (内存的边界与信任)在学习 C/C 的初期我们经常会遇到数组越界的问题。多数情况下C 不会在运行时进行边界检查。为什么因为 C/C 的设计哲学是“You don’t pay for what you don’t use”绝不为你不使用的功能付出代价。运行时检查边界需要消耗 CPU 时钟周期C/C 选择了极致的性能把内存的控制权完全信任并交给了程序员。但这也埋下了安全隐患黑客可以利用这个漏洞比如经典的缓冲区溢出攻击 Buffer Overflow篡改内存中相邻块重要数据的值甚至修改函数的返回地址来执行恶意代码。“Cpp will not complain the memory access, but the os will.” (C 不会抱怨你的内存访问但操作系统会。)如果你越界访问了不属于你的内存页操作系统就会无情地介入并赏你一个Segmentation Fault (段错误)然后杀掉你的进程。数据与内存结合应用内存不仅要存得对还要读得快。在 C/C 中二维数组在内存中是按行连续存储的。Row by row access better than col by col access. (按行访问远快于按列访问)补充知识这背后的核心是CPU Cache缓存的空间局部性。当你读取数组一个元素时CPU 会把包含该元素的整个 Cache Line通常是 64 字节一起搬进高速缓存。如果按行遍历接下来的数据已经在 Cache 里了Cache Hit如果按列遍历每次跳跃都会导致缓存未命中Cache Miss性能差异可能会达到几十倍Lec 02 Bits, Bytes, and Integers位运算符号 shift operations位运算是计算机最喜欢的底层操作主要有左移和右移。位运算符的基本作用左移 (Left Shift):丢弃最高位在右侧补 0。相当于乘以 2。右移 (Right Shift):分为两种逻辑右移 (Logical Shift):左侧一律补 0。通常用于无符号数。算术右移 (Arithmetic Shift):左侧补最高位符号位的值。用于有符号数保证右移后负数依然是负数。类型转换有关的 surprises在 C 语言中无符号数 (Unsigned) 和有符号数 (Signed) 混用是一个巨大的灾难现场。核心规则当一个表达式中同时存在有符号数和无符号数时C 语言会隐式地将有符号数强制转换为无符号数然后再进行比较或运算。仔细看下面的幻灯片比如-1 0U这个比较直觉上-1当然小于0但因为0是0U(无符号)-1会在底层被解释为无符号数的最大值UMAX所有比特位全为 1。所以比较变成了UMAX 0结果居然是FalseLec 03 Bits, Bytes, and Integers cont无符号加法与溢出 (Overflow)无符号数的加法在底层就像是一个时钟表盘本质是模运算 (Modular Arithmetic)。如果两个数相加超过了系统能表示的最大值它不会报错而是会“绕一圈”回到起点Wraps around。这就是溢出。⚠️ Risky Code Block无符号数永远 0因为无符号数永远不可能是负数在写循环条件时非常容易写出“死循环”Bug。看看下面幻灯片里的例子for (unsigned i cnt-2; i 0; i--)。你以为当i减到0之后再减1就会变成-1然后退出循环错0 - 1在无符号数下会溢出变成最大的正数UMAX所以i 0这个条件永远为真。这就是为什么说“你想耍点小技巧的时候会变得十分诡异”。如何优雅地解决将判断条件改为形式或者使用size_t(它本质上是平台字长的无符号整数) 并配合合理的边界检查永远不要去测试无符号数是否小于 0。Byte ordering (字节序)一个跨越多个字节的数据比如 4 字节的int在内存中是怎么排列的大端序 (Big Endian):最高有效字节最重要的数据存在最前面低地址。类似人类的阅读习惯。小端序 (Little Endian):最低有效字节存在最前面低地址。x86 和 ARM 处理器通常用这种。课外故事补全“Endian” 这个词出自乔纳森·斯威夫特的《格列佛游记》。在小人国里人们为了“吃白煮蛋应该从大头打破还是从小头打破”爆发了战争。计算机科学家借用了这个概念大头打蛋派就是 Big-Endian小头打蛋派就是 Little-Endian。这只是存放数据的两种习惯并无绝对优劣但在网络传输时网络字节序统一规定为大端序必须注意大小端的转换。C Integer 判断 (有趣的谜题)理解了前面的隐式转换和溢出就可以来看看这些经典的坑人 Puzzle 了用来检验自己是否真的理解了底层的位运算和比较规则。Lec 04 Floating Point昔日留言回应“不理解。 -2025/9/26”别急随着时间推移现在的我来为你彻底讲明白浮点数这座大山浮点数动态范围 (Dynamic Range)浮点数为什么能在 32 个 bit 里面表示比int范围大得多的数字并且还能表示小数答案是 IEEE 754 标准它把数字表示成了类似科学计数法的形式V (-1)^s * M * 2^E符号位 s (Sign):决定正负。指数 exp (Exponent):决定数字的范围大小类似于 10 的多少次方。尾数 frac (Mantissa/Fraction):决定数字的精度。你曾经困惑的“去规范化”与“规范化”到底是什么通常情况下规范化数为了省掉一个 bit 的空间尾数的小数点前默认总是隐藏着一个1即1.xxxx。这就是规范化数 (Normalized numbers)用来表示绝大多数正常的数字。但问题来了如果我们要表示非常非常接近于0的极小数字怎么办如果全是1.xxxx那能表示的最小的数就卡在某个值下不去了0 周围会出现一段无法表示的“空洞”。所以规定了去规范化数 (Denormalized numbers)当指数部分全是 0 时触发“去规范化”模式。此时尾数部分的小数点前不再隐藏1而是变成了0即0.xxxx。它的主要意义就是为了表示非常接近于 0 的极小数填补 0 周围的空洞实现“逐渐下溢 (Gradual Underflow)”让数字能平滑地过渡到绝对的 0。动态范围解释动态范围就是浮点数能表示的分布跨度。从 0 开始往上走先是密集的“去规范化数”然后是“最小的正规范化数”接着越来越稀疏直到“最大的规范化数”。下图非常直观地展示了这种在数轴上“越靠近 0 越密集越远离 0 越稀疏”的特性。Round action (舍入机制)当一个数字不能被精确的浮点数表示时我们需要舍入。IEEE 标准有几种舍入模式向零舍入、向下舍入、向上舍入。但最重要的是默认模式向偶数舍入 (Round to nearest even)。为什么不直接“四舍五入”在统计学中如果你总是遇到.5就向上舍入比如 1.5 变 22.5 变 3那么在一个庞大的数据集中总体平均值就会不自然地偏大这就是所谓的统计偏差。采用“向偶数舍入”Banker’s Rounding 银行家舍入法1.5 会变成 2但 2.5 遇到半中间时会向最近的偶数舍入变成 2。这样一半时间往上一半时间往下总体误差会在宏观上互相抵消。Round in binary data (二进制里的舍入)在二进制里“偶数”意味着最末位Least Significant Bit是0。如果后面的数字不到一半就直接丢掉。如果后面的数字超过一半就进位。如果正好卡在中间也就是后面正好是10000...那就看要保留的最后一位是1就进位变成0偶数是0就保持0已经是偶数。
延伸阅读

更多相关文章

2026/9/14 3:18:35

CMU 15-213 CSAPP:机器级编程与内存的暗黑魔法(Machine-Level)

继上一篇探讨了数据表示与浮点数之后,这篇笔记我们将深入 CPU 的视角。看看我们用高级语言写的 C/C 代码,是如何被翻译成机器指令、如何在寄存器和内存之间穿梭,以及稍不留神就会引发毁灭性灾难的“缓冲区溢出”到底是怎么发生的。Lec 05 Mac…

2026/9/10 14:45:36

Claude Code Skills开发指南与面试应用

1. 面试官问题的深层含义解析当面试官问出"你说你写代码都是用的Claude Code,那你自己有写过Claude Code的Skills吗?"这个问题时,实际上是在考察以下几个方面的能力:1.1 技术工具的理解深度面试官首先想确认的是&#x…

2026/9/6 8:47:30

高效工具链管理系统Hyde的设计与实践

1. 项目背景与核心价值"工具公告hyde"这个看似简单的标题背后,实际上隐藏着一个高效工具链管理系统的设计理念。作为从业十余年的全栈开发者,我见过太多团队在工具管理上踩坑——版本混乱、配置丢失、环境冲突这些问题几乎每天都在消耗开发者的…

2026/9/14 12:34:34

基于MATLAB的车道线检测:Canny边缘检测与霍夫变换实战解析

简介:基于MATLAB的车道线检测系统源码与配套PDF文档,主要面向需要完成毕业设计、课程设计或期末大作业的高校学生与开发者。代码完整可直接运行,实现车道线识别、转向预测等核心功能。资源共5个文件,包含2段mp4实操演示视频、1份P…

2026/9/14 12:34:34

极坐标牛拉法九节点潮流计算的MATLAB实现与雅可比矩阵解析

简介:面向电力系统专业学生与科研人员的极坐标牛顿-拉夫逊法潮流计算9节点MATLAB程序资源,解决的是极坐标形式下潮流方程组的构建、雅可比矩阵计算与迭代收敛问题,适合课程设计、毕业设计或入门的仿真分析。资源包共6个文件、约160KB&#xf…

2026/9/14 12:34:34

用AI语言引擎破解游戏出海买量成本与本地化困局

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/14 12:29:34

font-awesome图标字体加载失败排查与构建优化:从woff2 404到性能压降

简介:开发工具 Font Awesome 压缩版样式文件,是面向 Web 前端开发者的图标字体工具资源,适用于需要在网页中快速加载矢量图标、减少图片请求的个人站点、企业官网或后台管理系统等场景。文件采用单一 CSS 格式,整个资源包仅含 1 个…

2026/9/14 2:17:50

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/14 0:03:22

KCF目标跟踪算法与OTB工程实现:毕业设计实战解析

简介:这是一份基于KCF核相关滤波算法、融合尺度池与抗遮挡处理的目标检测跟踪MATLAB完整源码,主要面向计算机相关专业准备毕业设计、课程设计或期末大作业的学生,也适合需要项目实战练习的初学者。源码在OTB数据集上完成验证,能够…

2026/9/14 0:03:22

语音情感识别实战:Keras实现LSTM、CNN、SVM与MLP多模型对比

简介:面向语音情感识别入门与进阶开发者,这份基于Keras的项目源码完整实现了LSTM、CNN、SVM、MLP四种模型,兼容Python3.8与Keras/TensorFlow2环境。压缩包内含49个文件,大小约70.31MB,主体包括Python脚本、yaml/json配…

2026/9/14 11:59:31

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/14 11:22:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码