阅读:0
作者:严长生
<float.h>头文件详解
<float.h> 头文件没有定义任何函数或者类型,仅定义了一些与浮点数特性有关的宏。
在不同的平台和不同的编译器下,浮点数的特性可能会有所不同,用户可以读取该头文件中的宏来了解当前环境下的浮点数特性。
要想学习该头文件的内容,必须了解浮点数在内存中的存储,本文仅对浮点数的存储格式做了简要介绍,更多内容请猛击《小数在内存中是如何存储的,揭秘诺贝尔奖级别的设计(长篇神文)》一文。
C语言标准规定,浮点数在内存中以科学计数法的形式来存储,具体形式为:
<float.h> 头文件对 float、double 和 long double 三种类型的浮点数进行了说明,并且宏的命名也非常规范,以
注意,FLT_EVAL_METHOD 和 DECIMAL_DIG 是在 C99 标准中新加入的两个宏。
在不同的平台和不同的编译器下,浮点数的特性可能会有所不同,用户可以读取该头文件中的宏来了解当前环境下的浮点数特性。
要想学习该头文件的内容,必须了解浮点数在内存中的存储,本文仅对浮点数的存储格式做了简要介绍,更多内容请猛击《小数在内存中是如何存储的,揭秘诺贝尔奖级别的设计(长篇神文)》一文。
C语言标准规定,浮点数在内存中以科学计数法的形式来存储,具体形式为:
flt = (-1)sign × mantissa × baseexponent
对各个部分的说明:- flt 是要表示的浮点数。
- sign 用来表示 flt 的正负号,它的取值只能是 0 或 1:取值为 0 表示 flt 是正数,取值为 1 表示 flt 是负数。
- base 是基数,或者说进制,它的取值大于等于 2(例如,2 表示二进制、10 表示十进制、16 表示十六进制……)。数学中常见的科学计数法是基于十进制的,例如 6.93 × 1013;计算机中的科学计数法可以基于其它进制,例如 1.001 × 27 就是基于二进制的,它等价于 1001 0000。
- mantissa 为尾数,或者说精度,是 base 进制的小数,并且 1 ≤ mantissa < base,这意味着,小数点前面只能有一位数字;
- exponent 为指数,是一个整数,可正可负,并且为了直观一般采用十进制表示。
<float.h> 头文件对 float、double 和 long double 三种类型的浮点数进行了说明,并且宏的命名也非常规范,以
FLT_
开头的表示宏用来描述 float 类型的特性,以DBL_
开头的表示宏用来描述 double 类型的特性,以LDBL_
开头的表示宏用来描述 long double 类型的特性。宏 | 取值 | 说明 |
---|---|---|
FLT_RADIX | 大于等于 2 |
表示基数或者进制,也即上面公式中 base 的值。 FLT_RADIX 对所有浮点数类型(float、double 和 long double)都有效,也就是说,所有浮点数类型都必须采用相同的种基数(进制)。 |
FLT_MANT_DIG DBL_MANT_DIG LDBL_MANT_DIG |
基数(进制)为 FLT_RADIX 时,尾数 mantissa 的最大长度(最大位数),也可以说是浮点数的精度。注意,这里所说的长度包含了整数部分和小数部分。 | |
FLT_DIG DBL_DIG LDBL_DIG |
大于等于6 大于等于10 大于等于10 |
转换成十进制形式后,小数点后精确数字(能够保证精度的数字)的位数。 |
FLT_MIN_EXP DBL_MIN_EXP LDBL_MIN_EXP |
基数(进制)为 FLT_RADIX 时,规格化浮点数的指数(也即 exponent)的最小值(为负数)。 | |
FLT_MIN_10_EXP DBL_MIN_10_EXP LDBL_MIN_10_EXP |
小于等于-37 小于等于-37 小于等于-37 |
转换成十进制形式后,规格化浮点数的指数的最小值(为负数)。 |
FLT_MAX_EXP DBL_MAX_EXP LDBL_MAX_EXP |
基数(进制)为 FLT_RADIX 时,规格化浮点数的指数(也即 exponent)的最大值(为正数)。 | |
FLT_MAX_10_EXP DBL_MAX_10_EXP LDBL_MAX_10_EXP |
大于等于 37 大于等于 37 大于等于 37 |
转换成十进制形式后,规格化浮点数的指数的最大值(为正数)。 |
FLT_MAX DBL_MAX LDBL_MAX |
大于等于 1E+37 大于等于 1E+37 大于等于 1E+37 |
最大的有效浮点数的值(为正数),也即浮点数的最大值。 |
FLT_EPSILON DBL_EPSILON LDBL_EPSILON |
小于等于 1E-5 小于等于 1E-9 小于等于 1E-9 |
1 和大于 1 的最小浮点数之间的差值。 |
FLT_MIN DBL_MIN LDBL_MIN |
小于等于 1E-37 小于等于 1E-37 小于等于 1E-37 |
最小的有效浮点数的值(为负数),也即浮点数的最小值。 |
FLT_ROUNDS |
浮点数的舍入模式,可能的取值有:
FLT_ROUNDS 对所有浮点数类型(float、double 和 long double)都有效,也就是说,所有浮点数类型都必须采用相同的舍入模式。 |
|
FLT_EVAL_METHOD |
FLT_EVAL_METHOD 用来指明在表达式求值(尤其是数学运算)过程中是否需要提升浮点数的类型,可能的取值有:
FLT_EVAL_METHOD 对所有浮点数类型(float、double 和 long double)都有效,也就是说,所有浮点数类型都必须采用相同的类型提升。 提升类型能够提高浮点数的精度,让表达式的结果更加精确。在 x87 结构的浮点数运算器下,FLT_EVAL_METHOD 默认为 2;在 K&R C 中,FLT_EVAL_METHOD 的默认值为 1;在其它大多数情况下,FLT_EVAL_METHOD 的默认值为 0。 对于 GCC,在 32 位 x86 环境下,FLT_EVAL_METHOD 默认为 2;在 64 位 x86 环境下,FLT_EVAL_METHOD 默认为 0(可以通过编译选项 -mfpmath=387 将 FLT_EVAL_METHOD 的值设置为 2)。 |
|
DECIMAL_DIG | 在不损失精度精度的情况下,能够将 long double 转换成至少 DECIMAL_DIG 个十进制数字;反过来,也能将至少 DECIMAL_DIG 个十进制数字转换成 long double。也就是说,DECIMAL_DIG 是用于 long double 序列化和反序列化时的十进制精度。 |
注意,FLT_EVAL_METHOD 和 DECIMAL_DIG 是在 C99 标准中新加入的两个宏。