double 也就是双精度浮点数,它主要分成两大类形式,一类是代码源码里可以书写的字面量形式,另一类是内存底层 IEEE754 标准规定的二进制存储形式,同时还包含运算之后产生的特殊值形式,很多初学者容易混淆,以为 double 只有普通小数这一种写法,实际上写代码的时候可以用普通小数写法科学计数法写法来定义 double 变量,落到内存之后又会拆分成符号位指数位尾数位的二进制结构,并且还存在正常值非规格化数无穷大 NaN 这些特殊内部形式,区分清楚不同形式,才能理解 double 在赋值运算输出时出现的各种表现,尤其是科学计数法写法和特殊值形式,是很多报错和异常计算的来源,掌握每一种形式的定义适用场景和识别方法,后续写代码调试 double 相关计算问题的时候,就可以快速定位是字面量书写问题还是底层存储形式带来的异常。
一 源码层面 double 字面量书写形式
这一层是程序员写代码时直接输入给编译器的形式,编译器会把这些字面量转换成底层 IEEE754 二进制 double 存储形式。
| 书写形式 | 说明 | 示例 |
|---|---|---|
| 普通十进制小数形式 | 最常用,包含整数部分小数点小数部分,可以带正负号 | 3.14 -12.5 0.0 |
| 科学计数法形式 | 使用 e 或者 E 表示 10 的幂次,适合很大或者很小数值 | 1.2e5 也就是 120000 4.5E-3 也就是 0.0045 |
| 整数隐式转换形式 | 直接写整数,编译器自动转成 double 形式存储 | 100 自动转为 100.0 的 double |
补充要点,部分语言里面如果字面量不加后缀默认就是 double,而 float 一般需要加 f 后缀,这点是区分 double 字面量和 float 字面量的关键。
二 内存底层 IEEE754 double 内部形式
double 固定 64 位,内存里的二进制形式分成四类,这是硬件层面真实存储形式。
1 规格化数形式
这是最常用的正常数值形式,指数位不是全 0 也不是全 1,尾数位携带隐含前导 1,日常普通小数大部分都属于规格化数,可以表示绝大多数正常范围内的数值,有效精度保持 15 到 17 位十进制有效数字。
2 非规格化数形式
指数位全部为 0,没有隐含前导 1,作用是支持非常接近 0 的极小数值,实现渐进下溢,也就是数值越来越靠近 0 的时候,不会直接突然变成 0,可以平滑过渡,这个形式主要用来处理下溢场景,有效精度会比规格化数更低。
3 无穷大形式
指数位全部为 1,尾数位全部为 0,通过符号位区分正无穷大与负无穷大,代码里面一般记为 Infinity,比如正数除以 0 就会得到正无穷大形式的 double。
4 NaN 非数字形式
指数位全部为 1,尾数位不全为 0,代表不是合法数字,NaN 还可以细分安静 NaN 和信号 NaN,安静 NaN 可以继续参与运算不会触发硬件异常,信号 NaN 一般会在运算时触发异常,负数开平方非法运算就会产生 NaN 形式的 double。
三 特殊补充 输出展示形式
程序打印 double 的时候,还会有两种展示形式,一种是普通小数打印,另一种是自动切换成科学计数法打印,这个只是显示格式,底层依然是同一个 double 二进制形式,不会改变它本身存储结构。
四 不同形式转换要点
第一步 书写字面量,选择普通小数或者科学计数法形式编写 double 数值。
第二步 编译器解析字面量,按照 IEEE754 规则,转换成对应的规格化或者非规格化二进制 double 形式。
第三步 运算过程,计算结果如果超出正常范围,就会转换成无穷大形式,如果运算非法,就会变成 NaN 形式。
第四步 打印输出,根据格式化参数,选择普通小数或者科学计数法形式展示这个 double。
【常见问题】
问题 1 double 有什么形式里面的规格化数和非规格化数区别是什么
回答 1 double 有什么形式里面的规格化数指数位非全 0 非全 1,带隐含前导 1,精度更高,非规格化数指数位全 0,没有隐含前导 1,专门用来表示靠近 0 的极小数值,实现渐进下溢,精度低于规格化数。
问题 2 double 有什么形式里面科学计数法写法是不是单独的存储形式
回答 2 double 有什么形式里面科学计数法只是源码书写形式,不是底层独立存储形式,编译器解析之后依旧会转换成标准 IEEE754 二进制规格化 double 存储形式,只是写代码的时候方便表达超大或者超小数值。
问题 3 double 有什么形式里面 NaN 有哪两种细分形式
回答 3 double 有什么形式里面 NaN 分为安静 NaN 和信号 NaN,安静 NaN 参与运算不会触发硬件异常,信号 NaN 在参与运算的时候会触发浮点异常,一般非法数学运算生成的大多是安静 NaN。
问题 4 double 有什么形式中正无穷大是怎么构成的
回答 4 double 有什么形式中正无穷大属于底层特殊形式,指数位全部为 1,尾数位全部为 0,符号位为 0,正数除以零就会生成这个正无穷大形式的 double。
【免责申明】
本文基于 IEEE754 双精度浮点数标准进行讲解,不同编程语言编译器以及 CPU 浮点实现会存在细微差异,相关内容仅作为技术学习参考,不保证适配所有开发环境,项目实际开发请查阅对应语言官方文档,因直接参考本文内容进行开发产生的相关风险由使用者自行承担。


