1 浮点类型简介
浮点型是C++定义的基本类型。类型float、double和long double分别表示单精度浮点数、双精度浮点数和扩展精度浮点数。在Visual Studio中,float类型用4个字节表示,double和long double用8个字节表示。
默认的浮点字面值常量为double类型。在数值的后面加上F或者f表示单精度,在数值后面加上L或者l表示扩展精度。
float x = 3.1415F;
double y = 3.1415;
long double c = 3.1415L;
2 浮点类型的存储方式
2.1 单精度浮点数的存储方式
2.1.1 结构
在前文中提到,单精度浮点float类型占4个字节,即4×8=32位。在32位二进制数中,包含了符号、指数和尾数三个部分,如图1所示。
图1 单精度浮点数的结构
可以用十进制或者科学记数法来表示浮点数。十进制的表示方式在“1 浮点类型简介”中已经介绍。科学记数法的表示方式如下
float x = 1.23E3F;
float y = -4.56e-2f;
对于单精度浮点数类型的变量x,其符号为正,指数为3,尾数为1.23;对于变量y,其符号为负,指数为-2,尾数为-4.56。
2.1.2 存储方式
对于单精度变量x
float x = 10.125f;
其在内存中的存储方式是怎样的呢?首先要将x变成二进制格式,二进制与十进制的对应如表1所示:
表1 二进制与十进制的对应关系
二进制 | 1000 | 100 | 10 | 1 | 0.1 | 0.01 | 0.001 | 0.0001 |
十进制 | 8 | 4 | 2 | 1 | 0.5 | 0.25 | 0.125 | 0.0625 |
根据表1所示,因为变量x的值10.125,所以其转换成二进制后的格式为1010.001。
接下来将其再转换为科学计数法的方式,将小数点向左移动3位,即指数为3,因此此时x的表达方式是2进制,所以底数为2。即x的二进制科学计数法的格式为1.010001×2^3。所以,对于值为10.125的单精度浮点类型的变量x来说,其符号位为正,指数为为3,尾数为010001。
需要注意的是,对于图1所示的符号位,0表示正数,1表示负数。而指数位的起始值是127,如果此时指数为3,则指数位的值是127+3=130,即10000010,其结构如图2所示。
图2 10.125的存储方式
其二进制格式为0100 0001 0010 0010 0000 0000 0000 0000,十六进制格式为41 22 00 00。因为变量使用主机字节序存储(大头big-endian),即低地址保存数值的低位,高地址保存数值的高位,所以值为10.125的单精度浮点变量x的值是00 00 22 41。
2.1.3 取值范围及精度
(1)取值范围
在“2.1.2 存储方式”中提到,单精度浮点数float保存指数的内存大小是8位,且起始值是127,所以浮点数指数的最大值是(2^8-1)-127=128。则单精度浮点数float的取值范围是-2^128~2^128,即-3.4E38~3.4E38。
(2)精度
在“2.1.2 存储方式”中提到,单精度浮点数float保存尾数的内存大小是23位,2^(-23)≈0.000000119,四舍五入为0.0000001,即7位。也就是说,将浮点数转化为二进制科学表达式后,其有效位数为7时,都可以精确表示,即精度为7位。
例如:
float x = 1234.567f;
此时x的值为1234.567;
float y = 1234.5678f;
此时y的值是1234.566。
2.2 双精度浮点数的存储方式
2.2.1 结构
在前文中提到,双精度浮点double类型占8个字节,即8×8=64位。在64位二进制数中,包含了符号、指数和尾数三个部分,如图3所示。
图3 双精度浮点数结构
2.2.2 存储方式
双精度浮点数double与“2.1.2 存储方式”中提到的单精度浮点数float的存储方式相同。
2.2.3 取值范围及精度
(1)取值范围
在“2.2.2 存储方式”中提到,双精度浮点数double保存指数的内存大小是11位,且起始值是1023,所以浮点数指数的最大值是(2^11-1)-1023=1024。则双精度浮点数double的取值范围是-2^1024~2^1024,即-1.79E308~1.79E308。
(2)精度
正如“2.1.3 取值范围及精度”中提到的计算单精度浮点数float精度的方法,双精度浮点数double的尾数是52位,所以双精度浮点数double的精度是15位。