<float.h> 头文件没有定义任何函数或者类型,仅定义了一些与浮点数特性有关的宏。
在不同的平台和不同的编译器下,浮点数的特性可能会有所不同,用户可以读取该头文件中的宏来了解当前环境下的浮点数特性。
要想学习该头文件的内容,必须了解浮点数在内存中的存储,本文仅对浮点数的存储格式做了简要介绍,更多内容请猛击《小数在内存中是如何存储的,揭秘诺贝尔奖级别的设计(长篇神文)》一文。
C语言标准规定,浮点数在内存中以科学计数法的形式来存储,具体形式为:
对各个部分的说明:
<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_DIGLDBL_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_EVAL_METHOD | FLT_EVAL_METHOD 用来指明在表达式求值(尤其是数学运算)过程中是否需要提升浮点数的类型,可能的取值有:
提升类型能够提高浮点数的精度,让表达式的结果更加精确。在 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 标准中新加入的两个宏。