浮点型数据(float,double,logn double)介绍
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
浮点型数据(float,double,logn double)介绍
1. float, double, 以及long double
前面所说的数据类型只能用于处理整数。如果我们需要使用小数,就要使用浮点类型(floating-point)。C 提供了三种浮点类型:float, double, 以及long double。注意,unsigned/signed 不能用于修饰浮点类型。浮点类型可以处理正数,也能处理负数。没有无符号浮点型。
C 标准要求float 类型至少要能精确表示到小数点后6位。float 一般是32 位的。
C 标准规定double 类型至少要能精确到小数点后10 位。double 通常是64 位的。
C 还提供了long double 类型,目的是提供一种比double 更加精确的类型。然而,C 标准仅仅规定long double 至少要和double 一样精确。long double 通常96 位或者128 位。
2. 声明浮点型变量
浮点型变量的声明和初始化与整型变量一样。例如:
float f_1, f_2;
double d_1;
float f_3 = 6.63;
long double ld_1;
3. 浮点型常量
浮点型常量有多种写法。其基本形式为:首先写整数部分(可以带符号),接着写小数部分,然后写e 或者E,最后再写一个有符号整数。例如:
+1.2E+5
1.5e-9
-5.0e10
其中e 或E 被称为阶码标志,e 或 E 后面的有符号整数被称为阶码。阶码代表10 的阶码次方。例如:+1.2E+5 的值是1.2 * 105。假设A 为e 前面的部分,N 是 e 后面的部分,则AeN 等于A * 10N。此外,正号可以省略不写。小数部分也不是必需的,也就是说,5e3 也是正确的。阶码标志和阶码也可以不写,如:13.5。小数点后面,阶码标志之前的那部分整数可以不写(9.E5),小数点之前的整数也可以不写(.96e-8),但是不能同时都不写。例如:
56.
3.14
3e6
.6E-8
注意:浮点型常量中不能有空格!例如:
3.21e -12 /* 有空格,错!*/
3.14 e5 /* 有空格,错!*/
浮点型常量默认是double 类型的。假设var_f 是float 类型的变量,如果有以下语句:
var_f = 9.0 * 3.0;
那么9.0 和 3.0 都是double 类型的常量。它们的乘积也是double 型的。在进行赋值的时候,这个乘积被转化成float 类型,然后再赋值给var_f。
当然,我们也可以指定浮点型常量的类型。在浮点型常量后面添上 f 或者F,编译器就会用float 类型来处理这个常量。例如:1.5f,2.1e6F。在后面添上l 或者L 的话,编译器会用long double 类型来处理这个常量。例如:4.1l,50.2E5L。最好用大写L,因为小写l 容易和数字1 混淆。
标准规定,对于float 型,E 后面的阶码的取值范围至少要达到-37 到+37。对double 和long double 的规定同样如此。
C99 新增了一种表示浮点型常量的格式:使用十六进制前缀(0x 或0X,0 是数字0,不是字母o ),用p 或P 代替前面所说的e 或E,而且阶码代表的是2 的阶码次方。例如:
0xb.1ep5
其中b 等于十进制中的11, .1e 等于1/16 加14/256, p5 等于25,也就是512。这个浮点型常量转换成十进制就是:(11 + 1/16 + 14/256)*25 = 5692
注意:并非所有编译器都支持C99 新增的这种格式!
4. 输出浮点数
格式限定符%f 命令printf 函数以十进制形式输出float 和double 类型的浮点数;%e 命令printf 函数以指数形式输出float 和double 类型的浮点数;%a 或%A 命令printf 函数以C99 新增的那种十六进制格式输出,但是并非所有编译器都支持。如果您要输出long double 类型的浮点数,请用%Lf,%Le,%La,或者%LA。例如:
/* showfloat.c –用两种形式表示浮点数*/
#include
int main(void)
{
float var_f = 5.0;
double var_df = 3.14e2;
long double var_ld = 6.51e-5;
printf("%f is equal to %e ", var_f, var_f);
printf("%f is equal to %e ", var_df, var_df);
printf("%Lf is equal to %Le ", var_ld, var_ld);
return 0;
}
输出如下:
5.000000 is equal to 5.000000e+00
314.000000 is equal to 3.140000e+02
0.000065 is equal to 6.510000e-05
注意:以上是我在Suse Linux 10 下使用gcc 4.02 编译运行得到的输出。如果使用Dev-C++ 4.9.9.2 编译运行本程序,则不能正常输出var_ld。大概是因为Dev-C++ 使用的编译器gcc 中,long double 是96 位的,而它使用函数库中的printf 函数却把long double 当作64 位的来处理。
5. 浮点数上溢(Overflow)和下溢(Underflow)
假设您的编译器中,float 最大只能达到3.4e38,如果有以下语句:
float toobig = 3.4E38 * 100.0f;
printf("%e ", toobig);
这必然导致上溢!因为toobig 无法表示3.4E38 和100.0f 的乘积。上溢的后果过去是没有定义的,不过现在 C 规定如果发生上溢,则产生一个表示无穷大的特殊值。因此,toobig 的值最终会变成一个表示无穷大的特殊值。进而,printf 函数会输出类似inf 或者infinity 的字眼。
对一个绝对值非常小的浮点数进行除法,并且导致这个浮点数的精度降低,称之为下溢。打个比方,假设3.1415e-10 除以10 后,变成0.3141e-10,这就是下溢。