C语言学习(十)C语言中的小数
小数的表示方式
小数分为整数部分和小数部分,他们之间用点号.分隔,如0.0、7.5、4.098、0.27、-987.333等都是合法小数,这是最常见的小数形式,我们称为十进制形式。
此外,小时也可以采用指数形式,如3.2x103、0.0345x106、100.2323x10-6等。
C语言同时支持以上两种小数形式。
C语言中小数的指数形式为:
aEn 或 aen
其中a为尾数部分,是一个十进制的数字。n为指数部分,是一个十进制整数。e或者E是一个固定字符,用于分隔尾数和指数部分,整个表达式相当于ax10n
C语言中小数的类型
通常有两种类型,分别是float和double。float称为单精度浮点型,double称为双进度浮点型。
在C语言中,小数的长度是固定的,这点和整数完全不同。float始终占用4个字节,double始终占用8个字节。
小数的输出
小数也可以用printf函数输出,包括十进制和指数形式,他们对应的格式控制符分别为:
- %f以十进制形式输出float类型
- %lf以十进制形式输出double类型
- %e以指数形式输出float类型,输出结果中e小写
- %E以指数形式输出float类型,输出结果中E大写
- %le以指数形式输出double类型,输出结果中e小写
- %lE以指数形式输出double类型,输出结果中E大写
例:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float a = 0.302;
float b = 128.101;
double c = 123;
float d = 112.64E3;
double e = 0.7623e-2;
float f = 1.23002398;
printf("a=%e \nb=%f \nc=%lf \nd=%lE \ne=%lf \nf=%f\n", a, b, c, d, e, f);
return 0;
}
运行结果:
a=3.020000e-01
b=128.100998
c=123.000000
d=1.126400E+05
e=0.007623
f=1.230024
代码说明:
- %f和%lf默认保留六位小数,不足六位以0补齐,超过6位按四舍五入截断。
- 将整数赋值给float变量时会变成小数
- 以指数形式输出小数时,输出结果位科学技术法(0<=尾数<10)
- b的输出结果看起来不像我们想的那样,他并未输出一个准确的结果,而是输出了一个近似值。这和小数在内存中的存储有关,我们下篇再分析。
另外,小数还有一种更加智能的输出方式,就是使用%g
。%g会对比小数的十进制形式和指数形式,以最短的方式来输出小数,让输出结果更加简练。所谓最短,就是输出结果占用最少的字符。
%g的使用:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float a = 0.00001;
float b = 30000000;
float c = 12.84;
float d = 1.229338455;
printf("a=%g \nb=%g \nc=%g \nd=%g\n", a, b, c, d);
return 0;
}
运行结果:
a=1e-05
b=3e+07
c=12.84
d=1.22934
代码分析:
- a 的十进制形式是 0.00001,占用七个字符的位置,a 的指数形式是 1e-05,占用五个字符的位置,指数形式较短,所以以指数的形式输出。
- b 的十进制形式是 30000000,占用八个字符的位置,b 的指数形式是 3e+07,占用五个字符的位置,指数形式较短,所以以指数的形式输出。
- c 的十进制形式是 12.84,占用五个字符的位置,c 的指数形式是 1.284e+01,占用九个字符的位置,十进制形式较短,所以以十进制的形式输出。
- d 的十进制形式是 1.22934,占用七个字符的位置,d 的指数形式是 1.22934e+00,占用十一个字符的位置,十进制形式较短,所以以十进制的形式输出。
需要注意的是:
- %g默认最多保留六位有效数字(包括整数和小数);%f和%e默认保留六位小数,只是小数部分
- %g不会在最后强加0来凑够有效数字位数,而%f和%e会在最后强加0来凑够小数部分位数
数字的后缀
在C语言中,一个数字是有默认类型的。对于整数,默认是int类型,对于小数,默认是double类型。
例:
long a = 100;
int b = 294;
float x = 52.55;
double y = 18.6;
100个294这两个数字默认是int类型的,将100赋值给a,必须从int转换为long类型,而将294赋值给b就不用转换了。
52.55和18.6这两个数字默认都是double类型的,将52.55赋值给x,必须先从double类型转换为float类型,而将18.6赋值给y就不用转换了。
如果不想让数字使用默认的类型,就可以给数字加上后缀,手动指明类型:
- 在整数后面紧跟l或者L(不区分大小写)表明该数字是long类型
- 在小数后面紧跟f或者F(不区分大小写)表明该数字是float类型
例:
long a = 100l;
int b = 294;
short c = 32L;
float x = 52.55f;
double y = 18.6F;
float z = 0.02;
虽然数字的类型变了,但是不意味着该数字智能赋值给指定的数据类型,他仍然可以赋值给其他类型,只要进行一下转换就可以了。
小数和整数相互赋值
在C语言中,整数和小数之间是可以相互赋值的:
- 将一个整数赋值给小数类型,在小数点后面加0就可以,加几个都无所谓
- 将一个小数赋值给整数类型,就得把小数部分丢掉(直接舍弃,而不是四舍五入),智能取整数部分,这会改变数字本来的值。
例:
#include <stdio.h>
int main(){
float f = 251;
int w = 19.427;
int x = 92.78;
int y = 0.52;
int z = -87.27;
printf("f = %f, w = %d, x = %d, y = %d, z = %d\n", f, w, x, y, z);
return 0;
}
运行结果:
f = 251.000000, w = 19, x = 92, y = 0, z = -87
如果需要更加深入的从底层了解小数,或者你想知道小数在内存中是如何存在的,请参考小数在内存中是如何存储的?定点数与浮点数各自的优势在哪?规格化浮点数与非规格化浮点数又表示什么?
更多推荐
C语言学习(十)C语言中的小数
发布评论