主要观点:
- 介绍了符合 IEEE 754 标准的浮点数,包括其结构、能力、限制及常见误区。
- 浮点数在编程中广泛使用,不同编程语言中名称不同但基于相同标准,且由 CPU 和 GPU 提供硬件支持。
- 浮点数有精度有限、结果非确定性等特点,存在特殊值(如无穷大、非数)及各种陷阱,如灾难性抵消等。
- 讨论了不同精度的浮点数格式(如单精度、双精度、半精度等)及其在不同应用中的适用性。
关键信息:
- 32 位单精度浮点数结构:1 位符号位、8 位指数位、23 位尾数位,精度约 7 位小数,指数范围 -126 到 127,存在 +0 和 -0。
- 64 位双精度浮点数结构:1 位符号位、11 位指数位、52 位尾数位,精度约 16 位小数,指数范围 -1022 到 1023。
- 浮点数精度随数值大小变化,接近零处更密集,远离零处更稀疏,如 10.5 和 32000 的精度不同。
- 整数能被精确表示的范围小于浮点数,64 位双精度浮点数可精确表示的最大整数为 2^53。
- 一些有限小数在二进制中不能精确表示,如 0.1,导致浮点数计算结果有差异。
- 比较浮点数时不应使用“==”运算符,而应使用“fabsf(b - a) < 0.000001”等方式判断是否接近。
- 灾难性抵消可能导致大数值浮点数相减时精度丢失或结果不准确。
- 结果在不同平台可能不同,编译器优化、不同浮点指令集、Fast Math 等因素都会影响计算结果。
- 浮点数单元的操作模式可作为全局状态影响计算结果,外部库可能改变这些模式。
- 特殊值包括零(有 +0 和 -0)、非规格化数、无穷大(正无穷和负无穷)、非数(NaN),NaN 会在运算中传播且与任何数比较都为 false。
- 16 位半精度浮点数(fp16)精度约 3 位小数,范围有限,在图形处理中使用,AI 领域还有 bf16 等更低精度格式。
重要细节:
- 浮点数在计算机内存中的结构比整数复杂,整数用连续位组合表示连续值,浮点数分为三部分。
- 不同编程语言中浮点数类型的名称和特性有所不同,如 C、C++、Java 等语言中的 float 和 double。
- 硬件支持的浮点类型主要有 32 位单精度和 64 位双精度,一些脚本语言只有 double 类型。
- 浮点数的精度、范围等特性在不同编程语言和平台上可能略有差异。
- 编译器的 Fast Math 功能可影响浮点计算的优化和结果,但可能破坏 IEEE 754 标准的合规性。
- 浮点数的运算性能受多种因素影响,如基本运算和超越函数的速度差异、向量指令集等。
- 不同平台对非规格化数的处理方式可能不同,有些平台会将其替换为零。
- 浮点数的舍入模式也有多种,如向负无穷、正无穷、零或最接近偶数舍入。
- 安静 NaN 和信号 NaN 有区别,但文中未详细讨论。
总结:浮点数在编程中很重要但也有诸多特性和陷阱,了解其结构和工作原理有助于更有效地使用和避免错误。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。