定点数与浮点数:数值在计算机中的表示
上一篇讲了整数、编码和补码,解决的是“机器怎么表示离散的整数值”。但现实世界里的数远不止整数。
例如:
- 温度可能是
36.5; - 概率可能是
0.125; - 科学计算里可能会出现
6.02 × 10²³; - 金融系统里又常常要求极高的精度控制。
这时候就会遇到一个很重要的问题:
计算机应该怎样表示带小数点的数,才能兼顾范围、精度和硬件实现成本?
这正是定点数和浮点数要解决的问题。它们看起来只是“不同格式”,实际上背后体现的是两种完全不同的设计取舍。
一、为什么整数表示不够用
如果计算机世界里只有整数,那很多真实问题都无法自然表达。
例如:
- 图像和音频处理中经常需要比例和采样值;
- 算法里常会遇到平均值、概率和权重;
- 图形学、物理模拟、机器学习更离不开实数近似表示。
因此计算机必须有办法表示“小数”。但机器本质上只有有限位数,这意味着:
- 不可能像数学那样无限精确;
- 必须在表示范围和表示精度之间做权衡;
- 某些数可以精确表示,某些数只能近似表示。
二、什么是定点数
定点数可以理解成:
小数点的位置事先固定不变。
例如约定一个 8 位数里,前 4 位表示整数部分,后 4 位表示小数部分。那么位模式 0011 1000 就可能表示 3.5。
这种方式的特点很直接:
- 表示规则简单;
- 硬件实现相对容易;
- 适合数值范围比较固定、精度要求明确的场景。
定点数在一些嵌入式、音视频、DSP 或对性能很敏感的场景中仍然常见,因为它的运算成本和可控性通常比较好。
三、定点数的优点和局限是什么
1. 优点:实现简单、成本较低
由于小数点位置固定,很多运算可以近似看成整数运算再配合统一缩放,这对硬件和某些低层程序都很友好。
2. 优点:精度更可控
如果业务清楚知道需要保留几位小数,比如金额到分、传感器数据到某个固定倍率,定点方案往往更稳定。
3. 局限:范围和精度很难兼顾
同样的位数下,如果给整数部分更多位,小数精度就下降;如果给小数部分更多位,可表示的整数范围就变小。
所以定点数更像一种“在固定区间内工作得比较好”的方案。
四、为什么还需要浮点数
如果要表示的数据范围跨度特别大,定点数就会很吃力。
例如:
0.0000011234567896.02 × 10²³
这些数如果都想用统一的小数点位置表示,就会非常别扭。
于是计算机引入了更灵活的思路:
不固定小数点位置,而是像科学计数法那样,把数表示成“有效数字 × 基数的指数次幂”。
这就是浮点数的核心思想。
五、浮点数的直觉:像科学计数法一样表示数
十进制科学计数法里,一个数可以写成:
1 | 1.2345 × 10³ |
浮点数也类似,只不过基数通常是 2,而不是 10。
所以一个浮点数大体由三部分组成:
- 符号位:表示正负;
- 指数部分:决定数值范围;
- 尾数或有效数部分:决定精度。
理解这一点之后,浮点数就不再神秘了。它本质上是在用有限位数,尽量同时保住“很大范围”和“还不错的精度”。
六、浮点数为什么能表示更大范围
关键就在指数。
如果没有指数,所有数都只能挤在同一个固定尺度里;有了指数后,就可以把小数点“浮动”到不同位置。
这意味着:
- 很小的数也能表示;
- 很大的数也能表示;
- 但代价是精度不再均匀。
也就是说,浮点数的核心优势是范围大,核心代价是只能近似表示很多实数。
七、IEEE 754 标准在做什么
现代计算机里最常见的浮点表示方式,基本都遵循 IEEE 754 标准。
它规定了:
- 单精度和双精度等常见格式;
- 符号位、指数位、尾数位如何组织;
- 特殊值如
0、无穷大、NaN 的表示方式; - 舍入规则和一些异常行为。
例如双精度浮点数通常使用 64 位:
- 1 位符号位;
- 11 位指数;
- 52 位尾数。
这套标准的意义很大,因为它让不同硬件、不同语言之间对浮点结果有了相对统一的基础约定。
八、为什么浮点数会出现“看起来不准”的问题
很多人第一次碰到这个问题,都是在代码里看到类似现象:
1 | 0.1 + 0.2 != 0.3 |
这不是语言出错,而是因为像 0.1 这样的十进制小数,在二进制浮点体系里往往不能被有限位数精确表示,只能存成一个最接近的近似值。
于是:
- 存储时已经有误差;
- 运算后误差还可能继续传播;
- 最后打印出来时就可能看到并不“整齐”的结果。
这说明一个很重要的事实:
浮点数不是数学上的实数,而是“有限精度的实数近似表示”。
九、什么时候更适合用定点,什么时候更适合用浮点
1. 定点更适合的场景
- 数值范围相对固定;
- 精度要求明确且固定;
- 对性能、成本、可控性要求较高;
- 不希望出现浮点误差扩散。
例如金额系统,很多时候更推荐用“分”这样的整数或定点思路来表示,而不是直接用二进制浮点做核心结算。
2. 浮点更适合的场景
- 数值范围跨度大;
- 需要表示很小或很大的量;
- 科学计算、图形学、机器学习等对实数近似表示更依赖。
所以两者没有谁“绝对更高级”,只是设计目标不同。
十、浮点数相关的几个重要概念
1. 精度
不是所有小数都能被精确表示。尾数位越多,能保留的有效数字越多。
2. 范围
指数位越多,可表示的数量级范围越大。
3. 舍入
无法精确表示时,必须舍入到最接近的可表示值。
4. 特殊值
IEEE 754 还定义了无穷大和 NaN,这对异常计算结果处理很重要。
十一、从工程角度看,这部分知识为什么重要
这不仅仅是考试题。
1. 能理解数值 bug 的来源
很多“为什么计算结果差一点点”的问题,本质上就是浮点近似导致的。
2. 能更合理地设计数据表示
例如金额、比例、计数、概率、传感器值,并不一定都该直接上浮点。
3. 能看懂语言和硬件的取舍
CPU 往往有专门的浮点运算单元,编译器和语言也会围绕这些格式做优化和约定。
十二、学习这部分时最容易踩的坑
1. 以为浮点数就是“精确小数”
浮点数大多数时候只是近似值,不是精确十进制。
2. 忽略定点数的现实价值
很多人以为现代系统里只剩浮点,其实在嵌入式、金额处理和某些高性能场景中,定点思想仍然非常实用。
3. 只记格式,不理解取舍
真正重要的不是背出位数分配,而是理解为什么要把位分给符号、指数和尾数,以及这背后代表了什么权衡。
总结
定点数和浮点数解决的,都是“机器如何表示非整数数值”这个问题,但它们代表了两种不同的设计思路:
- 定点数通过固定小数点位置,换来简单、稳定和可控;
- 浮点数通过引入指数,换来更大的表示范围;
- 浮点数能表达更丰富的数量级,但很多数只能近似表示;
- 真正理解这部分知识的关键,不是死记格式,而是看清范围、精度和实现成本之间的取舍。
把这一篇理解透之后,后面再看校验编码、数字逻辑和 CPU 运算单元时,会更容易意识到:机器对数值的处理,本质上都建立在“如何编码和表示”这件事上。
参考资源:
- 《深入理解计算机系统》
- IEEE 754 标准介绍
- What Every Computer Scientist Should Know About Floating-Point Arithmetic
- 《计算机组成与设计:硬件/软件接口》