C/C++ 数据类型 表示最大 最小数值 探讨

  • 2021 年 10 月 25 日
  • 筆記

 

C/C++中存储数字格式有整型和浮点型 字符型数据本质上也是以整型存储

 

整型

对于整型数据,最大值最小值很好计算

先确定对应数据型在本地所占用的字节数,同一数据型由于系统或者编译器的不同,所占字节不同,可以通过sizeof()函数查看,例如:

cout << sizeof(int) <<endl;

例如在我的电脑中 int 占用四个字节(即32位),1位符号位+31位数值位
所以int可表示的值得范围为 -2^31 — 2^31-1 (这里正负数不对称,减一是因为还有一个0)

同样的,对于整型都可以这么计算,通过所占字节数(即多少位)可以计算出它可以表示的最大最小值,需要注意的是对于无符号型,所有的位都是数值位,没有符号位,即没有负数。

 

浮点型

首先我们要知道,对于浮点型数据,计算机是以指数形式存储的。
即 a^b  a的b次方

具体格式
float型(通常为32位) 1位符号位+8位指数位+23位数值位(尾数位)

double型(通常为64位) 1位符号位+11位指数位+53位数值位(尾数位)

(这里数据型所占字节数可能也有差异,具体占用内存大小可通过之前的代码自行查看,这里选择一般情况作为举例)

顾名思义,符号位即0为正,1为负, 指数位表示次方大小,尾数位表示精度(precision)。和上面的式子对照,尾数位表示a,指数位表示b。这里尾数位的小数点默认在第一位最高位以后,以float为例,即尾数位最大表示的数为1.1111111111111111111111(二进制表示);不超过2。

例如 float 23位尾数位 即换算成十进制最大为2^23=8388608 所以float的精度位6-7位,6位精度可以保证,7位精度只能表示部分。
double 同理,精度为15-16位,15位精度可以保证正确,16位精度只能表示部分。

下面看float和double可以表示的最大值和最小值(这里最小值指最接近零的值)

float 理论上能表示的最大值:符号位为正 指数位最大127 尾数位全为1
即(2-2^22)^127 = 3.4028e+38
理论上最小值:(2-2^22)^-128 = 5.8776e-39

double 类型同样方法可以算的,不再赘述。

当然这只是理论值,具体数值在<float.h>头文件中有定义
打开float.h文件 可以看到看到以下代码:

#define DBL_DECIMAL_DIG 17                          // # of decimal digits of rounding precision
#define DBL_DIG 15                                  // # of decimal digits of precision
#define DBL_EPSILON 2.2204460492503131e-016         // smallest such that 1.0+DBL_EPSILON != 1.0
#define DBL_HAS_SUBNORM 1                           // type does support subnormal numbers
#define DBL_MANT_DIG 53                             // # of bits in mantissa
#define DBL_MAX 1.7976931348623158e+308             // max value
#define DBL_MAX_10_EXP 308                          // max decimal exponent
#define DBL_MAX_EXP 1024                            // max binary exponent
#define DBL_MIN 2.2250738585072014e-308             // min positive value
#define DBL_MIN_10_EXP (-307)                       // min decimal exponent
#define DBL_MIN_EXP (-1021)                         // min binary exponent
#define _DBL_RADIX 2                                // exponent radix
#define DBL_TRUE_MIN 4.9406564584124654e-324        // min positive value

#define FLT_DECIMAL_DIG 9                           // # of decimal digits of rounding precision
#define FLT_DIG 6                                   // # of decimal digits of precision
#define FLT_EPSILON 1.192092896e-07F                // smallest such that 1.0+FLT_EPSILON != 1.0
#define FLT_HAS_SUBNORM 1                           // type does support subnormal numbers
#define FLT_GUARD 0
#define FLT_MANT_DIG 24                             // # of bits in mantissa
#define FLT_MAX 3.402823466e+38F                    // max value
#define FLT_MAX_10_EXP 38                           // max decimal exponent
#define FLT_MAX_EXP 128                             // max binary exponent
#define FLT_MIN 1.175494351e-38F                    // min normalized positive value
#define FLT_MIN_10_EXP (-37)                        // min decimal exponent
#define FLT_MIN_EXP (-125)                          // min binary exponent
#define FLT_NORMALIZE 0
#define FLT_RADIX 2                                 // exponent radix
#define FLT_TRUE_MIN 1.401298464e-45F               // min positive value

查看源代码,可以看到float最大值和我们理论值相同,但最小值不一样,double类型同样如此
对于最小值是怎么算的,为什么这么算,这一点我也不是很懂,如果有大佬看到,希望大佬解释。