C语言复习(五)

float、double、long double

浮点数多用于金融和数学的程序。浮点数类型能表示包括小数在内更大范围的数。浮点数表示类似于科学记数法(即用小数乘以10的幂来表示数字)。

float

C标准规定,float 类型必须至少能表示6位有效数字,且取值范围至少是10^-37
~10^38。系统要存储一个浮点数要占用32位。其中8位表示指数的值和符号,剩下24位用于表示非指数部分(也叫做尾数或有效数)及其符号。

double

双精度。double 类型和 float 类型的最小取值范围相同,但至少必须能表示10位有效数字。一般情况下,double 占用64位而不是32位。一些系统将多出的 32 位全部用来表示非指数部分,这不仅增加了有效数字的位数(即提高了精度),减少了舍入误差。另一些系统把其中的一些位分配给指数部分,以容纳更大的指数,从而增加了可表示数的范围。无论哪种方法,double 类型的值至少有 13位有效数字,超过了标准的最低位数规定。

long double

比满足比 double 类型更高的精度要求。C只保证long double 类型至少与 double 类型的精度相同。

声明浮点变量

float a;
double b;
float c=6.63e-34;
long double d;

浮点常量的表示

  1. 有符号的数字,后面紧跟 e 或 E,可以省略小数部分,或者整数部分
    1
    2
    3
    4
    5
    6
    -1.56E+12
    2.87e-3
    .2
    4e16
    .8E-5
    100.

不要在浮点型常量中间加空格 如:1.56 E+12 (错误)

默认情况下,编译器假定浮点型常量为 double 类型的精度

1
float abc= 4.0 * 2.0;

其中的 4.0 和 2.0 常数默认为 double 类型计算后截断为float 类型。这样的程序运行速度会缓慢。使用 f 或 F 常量后缀,可以覆盖默认模式,比如:4.0f 或 2.0f 如果添加 l 或 F 可以变为 long double 类型 如:54.3L 和34.1l 建议使用大写,因为l小写与数字1 相似。

C99 标准添加了一种新的浮点型常量格式–用十六进制表示浮点型常量,即添加 Ox 或 OX ,用 p 和 P 分别代替 e 和 E,用 2的幂代替10的幂(p 计数法)。如:

1
Oxa.1fp10

a 十进制表示 10,.1f 是 1/16,f是15所以 为15/256, 加上 p10 表示 2^10或1024。Oxa.1fp10 表示(10+1/16+15/256)* 1024

注意:并非所有编译器都支持 C99

打印浮点值

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main (void)
{
float a=32000.0;
double b=2.14e9;
long double c=5.5e-6;
printf("%f & %e \n",a,a);
printf("%f & %e \n",b,b);
printf("%Lf & %Le \n",c,c);
getchar();
return 0;
}

第三个显示我有点费解,后来想到保证 6位有效数字,就可以理解了

浮点数的上溢和下溢

上溢

1
2
float toobig = 3.4E38 * 100.0f
printf("%e \n",toobig);

以上 3.4E38 float 最大范围值*正数,超过最大值,会出现上溢,打印显示 inf 或 infinity (或者无穷含义)

下溢

以 十 进 制 为 例, 把 一 个 有 4 位 有 效 数 字 的 数( 如, 0.1234E-10) 除 以 10, 得 到 的 结 果 是 0.0123E-10。 虽 然 得 到 了 结 果, 但 是 在 计 算 过 程 中 却 损 失 了 原 末 尾 有 效 位 上 的 数 字。 这 种 情 况 叫 作 下 溢( underflow)。

NaN
NOT a number

例 如, 给 asin() 函 数 传 递 一 个 值, 该 函 数 将 返 回 一 个 角 度, 该 角 度 的 正 弦 就 是 传 入 函 数 的 值。 但 是 正 弦 值 不 能 大 于 1, 因 此, 如 果 传 入 的 参 数 大 于 1, 该 函 数 的 行 为 是 未 定 义 的。 在 这 种 情 况 下, 该 函 数 将 返 回 NaN 值, printf() 函 数 可 将 其 显 示 为 nan、 NaN 或 其 他 类 似 的 内 容。
[美]史蒂芬·普拉达(Stephen Prata). CPrimer Plus(第6版)中文版 (Kindle 位置 1840-1842). 人民邮电出版社.

浮点数的舍入错误

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main(void)
{
float a,b;
a=2.0e20 +1.0;
b=a-2.0e20;
printf("%f \n",b);
getchar();
return 0;
}

出现这种问题的原因:flaot 的数字只能存储按指数比例缩放或放大的 6或7位有效数字。上面是20位,如果加1就是21位,所以出现错误

大部分总结的内容出自《C Primer Plus 》 书中。总结是为了方便本人理解与学习

(*^▽^*)