C语言浮点数
一、浮点数的观点
浮点数也称小数或实数。例如,0.0、75.0、4.023、0.27、-937.198 都是正当的小数。
C语言中接纳float和double关键字来界说小数,float称为单精度浮点型,double称为双精度浮点型,long double更长的双精度浮点型。
在任何区间内(如1.0 到 2.0 之间)都存在无限多个实数,盘算机的浮点数不能示意区间内所有的值。
二、点用内存的情形
我们先来测试一下float、double和long double三种浮点数据类型占用内存的字节数。
示例(book71.c)
/*
* 程序名:book71.c,此程序测试float、double和long double占用内存的字节数
* 作者:C语言手艺网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
int main()
{
printf("sizeof float is %d\n",sizeof(float));
printf("sizeof double is %d\n",sizeof(double));
printf("sizeof long double is %d\n",sizeof(long double));
}
运行效果
三、浮点数的精度
C尺度划定,float类型必须至少能示意6位有用数字,且取值局限至少是10^-37^~10^+37^。
double类型和 float类型的最小取值局限相同,但至少必须能示意10位有用数字。
long double,以知足比double类型更高的精度要求。不外,C只保证long double类型至少与double类型的精度相同。
看了上面这段文字,估量人人有点晕,在之前的整数章节中,long比int的占用的内存多,存放数据的值也就越大,并且有一个准确的局限,然则,为什么种种浮点数存放数据的值怎么就这么模糊呢?我先不注释缘故原由,浮点数的存储方式对照复杂,暂时不讨论,先用几个程序来测试一下它们的特征。
1、测试float类型
示例(book73.c)
/*
* 程序名:book73.c,此程序测试float的特征
* 作者:C语言手艺网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
int main()
{
float ff2=9.9; // 测试2位的浮点数
printf("ff2=%f\n",ff2);
if (ff2==9.9) printf("ff2==9.9\n");
float ff5=99.999; // 测试5位的浮点数
printf("ff5=%f\n",ff5);
if (ff5==99.999) printf("ff5==99.999\n");
float ff6=999.999; // 测试6位的浮点数
printf("ff6=%f\n",ff6);
if (ff6==999.999) printf("ff6==999.999\n");
float ff7=9999.999; // 测试7位的浮点数
printf("ff7=%f\n",ff7);
if (ff7==9999.999) printf("ff7==9999.999\n");
float ff8=99999.999; // 测试8位的浮点数
printf("ff8=%f\n",ff8);
if (ff8==99999.999) printf("ff8==99999.999\n");
}
运行效果
从程序的运行我们可以看出float数的两个特征:
1)float数据类型表达的是一个近似的数,不是准确的,小数点后的n位有误差,浮点数的位数越大,误差越大,到8位的时刻,误差了1,基本上不能用了。
2)用“==”可以对照两个整数或字符是否相等,然则,看起来相等的两个浮点数,就是不会相等。
2、测试double类型
示例(book74.c)
/*
* 程序名:book74.c,此程序测试double的特征
* 作者:C语言手艺网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
int main()
{
double ff2=9.9; // 测试2位的浮点数
printf("ff2=%lf\n",ff2);
if (ff2==9.9) printf("ff2与9.9相等。\n");
double ff12=999999999.99; // 测试12位的浮点数
printf("ff12=%lf\n",ff12);
if (ff12==999999999.99) printf("ff12与999999999.999相等。\n");
double ff13=9999999999.99; // 测试13位的浮点数
printf("ff13=%lf\n",ff13);
if (ff13==9999999999.99) printf("ff13与9999999999.999相等。\n");
double ff14=99999999999.99; // 测试14位的浮点数
printf("ff14=%lf\n",ff14);
if (ff14==99999999999.99) printf("ff14与99999999999.999相等。\n");
double ff15=999999999999.99; // 测试15位的浮点数
printf("ff15=%lf\n",ff15);
if (ff15==999999999999.99) printf("ff15与999999999999.999相等。\n");
double ff16=9999999999999.99; // 测试16位的浮点数
printf("ff16=%lf\n",ff16);
if (ff16==9999999999999.99) printf("ff16与9999999999999.999相等。\n");
double ff17=99999999999999.99; // 测试17位的浮点数
printf("ff17=%lf\n",ff17);
if (ff17==99999999999999.99) printf("ff17与99999999999999.999相等。\n");
double ff18=999999999999999.99; // 测试17位的浮点数
printf("ff18=%lf\n",ff18);
if (ff18==999999999999999.99) printf("ff17与99999999999999.999相等。\n");
}
运行效果
从程序的运行我们可以看出double数的两个特征:
1)double数据类型表达的也是一个近似的数,不是准确的,小数点后的n位有误差,浮点数的位数越大,误差越大,到17位的时刻,误差了1,基本上不能用了。
2)用“==”可以对照两个double数值是否相等。
3、测试long double类型
示例(book75.c)
/*
* 程序名:book75.c,此程序测试long double的特征
* 作者:C语言手艺网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
int main()
{
long double ff2=9.9; // 测试2位的浮点数
printf("ff2=%Lf\n",ff2);
if (ff2==9.9) printf("ff2与9.9相等。\n");
long double ff12=999999999.99; // 测试12位的浮点数
printf("ff12=%Lf\n",ff12);
if (ff12==999999999.99) printf("ff12与999999999.999相等。\n");
long double ff13=9999999999.99; // 测试13位的浮点数
printf("ff13=%Lf\n",ff13);
if (ff13==9999999999.99) printf("ff13与9999999999.999相等。\n");
long double ff14=99999999999.99; // 测试14位的浮点数
printf("ff14=%Lf\n",ff14);
if (ff14==99999999999.99) printf("ff14与99999999999.999相等。\n");
long double ff15=999999999999.99; // 测试15位的浮点数
printf("ff15=%Lf\n",ff15);
if (ff15==999999999999.99) printf("ff15与999999999999.999相等。\n");
long double ff16=9999999999999.99; // 测试16位的浮点数
printf("ff16=%Lf\n",ff16);
if (ff16==9999999999999.99) printf("ff16与9999999999999.999相等。\n");
long double ff17=99999999999999.99; // 测试17位的浮点数
printf("ff17=%Lf\n",ff17);
if (ff17==99999999999999.99) printf("ff17与99999999999999.999相等。\n");
long double ff18=999999999999999.99; // 测试17位的浮点数
printf("ff18=%Lf\n",ff18);
if (ff18==999999999999999.99) printf("ff17与99999999999999.999相等。\n");
}
运行效果
long double的测试效果与double相同。
4、测试总结
float只能表达6-7位的有用数字,不能用“==”判断两个数字是否相等。
double能表达15-16位有用的数字,可以用“==”判断两个数字是否相等。
long double占用的内存是double的两倍,但表达数据的精度和double相同。
在现实开发中,建议弃用float,只接纳double就可以,long double暂时没有需要,但不知道以后的操作系统和编译器对long double是否有改善。
四、浮点数的输出
float接纳%f占位符。
double接纳%lf占位符。测试效果证实,double不可以用%f输入,但可以用%f输出,然则不建议接纳%f,由于差异的编译器可能会有差异。
long double接纳%Lf占位符,注重,L是大写。
浮点数输出缺省显示小数点后六位。
浮点数接纳%lf输出,完整的输出花样是%m.nlf,指定输出数据整数部门和小数部门共占m位,其中有n位是小数。若是数值长度小于m,则左端补空格,若数值长度大于m,则按现实位数输出。
double ff=70001.538;
printf("ff=%lf=\n",ff); // 输出效果是ff=70001.538000=
printf("ff=%.4lf=\n",ff); // 输出效果是ff=70001.5380=
printf("ff=%11.4lf=\n",ff); // 输出效果是ff= 70001.5380=
printf("ff=%8.4lf=\n",ff); // 输出效果是ff=70001.5380=
五、常用的库函数
在接下来的内容中,我只先容double,不再先容float和long double两种数据类型相关的知识。
以下是常用的浮点数函数,必须掌握。
double atof(const char *nptr); // 把字符串nptr转换为double
double fabs(double x); // 求双精度实数x的绝对值
double pow(double x, double y); // 求 x 的 y 次幂(次方)
double round(double x); // double四舍五入
double ceil(double x); // double向上取整数
double floor(double x); // double向下取整数
double fmod(double x,double y); // 求x/y整除后的双精度余数
// 把双精度val分解成整数部门和小数部门,整数部门存放在ip所指的变量中,返回小数部门。
double modf(double val,double *ip);
另有一些数据盘算函数,如正弦、对数、指数等,现实开发中少少使用,人人要用的时刻再查资料,我就不先容了。
六、整数转换为浮点数
示例(book77.c)
/*
* 程序名:book77.c,此程序测试整数与浮点数的转换。
* 作者:C语言手艺网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
int main()
{
int ii=3;
int jj=4;
double dd;
dd=ii; // 可以
printf("dd is %.2lf\n",dd);
dd=ii/jj; // 不行
printf("dd is %.2lf\n",dd);
dd=(double)ii/jj; // 可以
printf("dd is %.2lf\n",dd);
}
运行效果
需要特别注重的是dd=ii/jj这一行代码,dd的值0,不是0.75,有点意外,以是,若是对整数转换为浮点数没有掌握,加(double)强制转换是个好办法。关于数据类型的转换,在《C语言数据类型转换》章节中将有更详细的先容。
七、应用履历
浮点数有一些坑,例如两个浮点数不相等和精度的问题,在现实开发中,我们经常用整数取代浮点数,由于整数是正确的,效率也更高。
例如人的身高一米七五,以米为单元,用浮点数示意是1.75米,若是以厘米为单元,用整数示意是175。
long整数的取值是-9223372036854775808\~9223372036854775807,有用数字是19位,而double的有用数字才15-16位,以是,整数可以表达的小数更大的数,更适用,贫苦也更少。
钱币:1.75元,若是接纳0.01元为单元就是175,接纳0.001元为单元就是1750,若是您说要更多小数怎么办?您这是钻牛角尖。
码农之道:高水平的程序员不容易掉坑里,注重,是不容易,不是不会,最好的方式是不要靠近坑。
八、科学计数法
在现实开发中,我们很少使用科学计数法,然则它经常出现在盘算机系统中,例如浮点数在内存中的存放方式就是科学计数法,以是我们照样有需要学习科学计数法。
科学记数法是一种记数的方式。把一个数示意成a与10^n^相乘的形式(1≤|a|\<10,n为整数),这种记数法叫做科学记数法。当我们要誊写或运算某个较大或较小且位数较多时,用科学记数法免去虚耗许多空间和时间。
例如:51400000000=5.14×10^11^,盘算机表达10的幂是一样平常是用E或e,也就是51400000000=5.14E11或5.14e11。
用科学记数法示意数时,不改变数的符号,只是改变数的誊写形式而已,可以利便的示意一样平常生涯中遇到的一些极大或极小的数 。如:光的速率大约是300,000,000米/秒;全世界人口数大约是:6,100,000,000,这样的数誊写和显示都很不利便,为了免去写这么多重复的0,将其表现为这样的形式:6,100,000,000=6.1×10^9^,即6.1E9或6.1e9。
0.00001=1×10^-5^,即绝对值小于1的数也可以用科学记数法示意为a乘10^-n^的形式。即1E-5或1e-5。
科学计数法接纳%e或%E输出,完整的输出花样是%m.ne或%m.nE,指定输出数据整数部门和小数部门共占m位,其中有n位是小数。若是数值长度小于m,则左端补空格,若数值长度大于m,则按现实位数输出。
示例(book78.c)
/*
* 程序名:book78.c,此程序测试浮点数据的科学计数法。
* 作者:C语言手艺网(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>
int main()
{
double dd;
dd=123000000;
printf("dd is %.2e\n",dd);
dd=-123000000;
printf("dd is %.2e\n",dd);
dd=0.0000000123;
printf("dd is %.2e\n",dd);
dd=-0.0000000123;
printf("dd is %.2e\n",dd);
}
运行效果
九、课后作业
1)编写示例程序,类似本章节的book71.c、book73.c、book74.c、book75.c、book77.c、book78.c,编译并运行它,程序员是写出来的,不是看出来的,熟能生巧,您天天的支出都有意义。
2)编写示例程序,测试浮点数赋值跨越取值局限的结果。
3)关于浮点数在内存中的存储方式,建议人人去百度一下(搜索关键字为C语言浮点数存储方式),领会一下相关的观点。
4)编写示例程序,测试把浮点数赋给整数变量的效果,并思索缘故原由。
5)本题作业建议在学完《C语言数据类型转换》后再做,由于有知识点交织,重写浮点数的常用库函数,实现其功效,函数的声明如下:
double FABS(const double x); // 求双精度实数x的绝对值
double ROUND(const double x); // double四舍五入
double CEIL(const double x); // double向上取整数
double FLOOR(const double x); // double向下取整数
// 把双精度val分解成整数部门和小数部门,整数部门存放在ip所指的变量中,返回小数部门。
double MODF(double val,double *ip);
十、版权声明
C语言手艺网原创文章,转载请说明文章的泉源、作者和原文的链接。
泉源:C语言手艺网(www.freecplus.net)
作者:码农有道
若是这篇文章对您有辅助,请点赞支持,或在您的博客中转发我的文章,谢谢!!!
若是文章有错别字,或者内容有错误,或其他的建媾和意见,请您留言指正,非常感谢!!!
0
珍藏
Allbet Gaming声明:该文看法仅代表作者自己,与本平台无关。转载请注明:张家口热线:C语言浮点数阳光在线www.0913esg.com(原诚信在线)现已开放阳光在线手机版下载。阳光在线游戏公平、公开、公正,用实力赢取信誉。
6码组:0 3 5 6 7 8坚持写下去,加油啊
皇冠注册平台www.huangguan.us是一个提供皇冠代理APP下载、皇冠会员APP下载、皇冠体育最新登录线路、新2皇冠网址的的体育平台。新皇冠体育官网是多年来值得广大客户信赖的平台,我们期待您的到来!看得很心潮澎湃