非法使用什么是浮点数数在main中

模拟试题1-1_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
模拟试题1-1
上传于||暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩21页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢帮我看看这个程序我用win tc为什么说错误 noname.c 14: 非法地使用浮点数在 main 函数中 下面是程序_百度知道作者:gfree.
博客:blog.focus-linux.net & linuxfocus.blog.chinaunix.net&&本文的copyleft归gfree.所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。======================================================================================================其实浮点数使用时的注意事项,是一个老生常谈的问题,我本来不想写这个东西的。但是论坛上偶尔还是会有一些朋友问一些浮点的问题,另外前几天写得一篇博文《有趣的问题:C的表达式x==x何时为假》在那篇文章中,通过x != x为假这一有趣的问题,引出一个特殊的浮点数值NaN。当时我还为了对比浮点与整数的转换,所以使用了memcpy来达到用0xff填充浮点数,来形成NaN。但是在评论中,发现有的朋友反而因为示例中的memcpy而没有注意到重点NaN。那么今天就重点说一下NaN,并顺带说一下浮点的其它陷阱。1. 浮点的精度限制。浮点数的存储格式与整数完全不同。大部分的实现采用的是IEEE 754标准,float类型,是1个sign bit,8 exponent bits,23 mantissa bits。而double类型,是1个sign bit,11 exponent bits,52 mantissa bits。至于浮点如何去表示小数,请自行搜索google。由于float使用的小数表示方法,导致浮点数值是有精度限制的。有限的精度就引发了浮点数值使用时的两个陷阱。1)交换定律不适用浮点数如有三个浮点数float x=1/3,y=1/6,z=1/7,而x*y/z不等于x*(y/z)#include &stdlib.h&#include &stdio.h&int main(void){&&&&float x = 1/3;&&&&float y = 1/6;&&&&float z = 1/7;&&&&if (x*y/z != x*(y/z)) {&&&&&&&&printf("Not equal!\n");&&&&}&&&&return 0;}编译输出:[fgao@fgao-vm-fc13 test]$ gcc -g test.c[fgao@fgao-vm-fc13 test]$ ./a.outNot equal!而对于整数来说,如果不发生溢出的情况下,x*y/z是等于x*(y/z)。2)浮点数的比较要使用范围比较如:#include &stdlib.h&#include &stdio.h&int main(void){&&&&float x = 0.123-0.11-0.013;&&&&if (x == 0) {&&&&&&&&printf("x is 0!\n");&&&&}&&&&if (-0. & x && x & 0.) {&&&&&&&&printf("x is in 0 range!\n");&&&&}&&&&return 0;}编译输出:[fgao@fgao-vm-fc13 test]$ gcc -g test.c[fgao@fgao-vm-fc13 test]$ ./a.outx is in 0 range!这两个都是比较常见的浮点陷阱,下面要说明的是浮点数值的两个exception1)infinite无限2)NaN即Not a Number其中NaN为最为特殊的一个“浮点值”——它不是一个合法的浮点值在前面的文章中,我使用memcpy构造了一个非法的浮点数值,它导致了x与自身比较的失败。那么,有的朋友会说平时谁会用memcpy去填充浮点啊,那么NaN就离我很远了啊。请看下面的例子:#include &stdlib.h&#include &stdio.h&int main(void){&&&&float x = 1/0.0;&&&&printf("x is %f\n", x);&&&&x = 0/0.0;&&&&printf("x is %f\n", x);&&&&return 0;}编译输出[fgao@fgao-vm-fc13 test]$ gcc -g test.c[fgao@fgao-vm-fc13 test]$ ./a.outx is infx is -nan当1除以0.0时,我们得到的是infinite,而是用0除以0.0时,得到的就是NaN。这里完全是普通的除法运算,也会产生NaN的情况。那么当使用除法的时候,对除数进行检查,保证其不为0.0是否就可以避免NaN了呢?再看下面的代码:#include &stdlib.h&#include &stdio.h&int main(void){&&&&float x;&&&&while (1) {&&&&&&&&scanf("%f", &x);&&&&&&&&printf("x is %f\n", x);&&&&}&&&&return 0;}编译执行[fgao@fgao-vm-fc13 test]$ ./a.outinfx is infnanx is nan示例代码中,调用scanf来得到用户输入的浮点数。令人惊讶的是,scanf作为C库函数是接受浮点数的这两种exceptions的,用户可以直接输入无限inf和NaN。而C库中究竟有多少种输入输出函数支持这两种exception,我也不知道。那么对于UI程序来说,当遇到浮点数值的时候,我们必须要判断该浮点数是否为一个合法的浮点数,要对用户输入值进行检查,或者说对于一切不属于本模块的浮点输入值都要进行检查。——我在我同事那就遇到一个开源库返回的浮点数为NaN,才引发的前文。以上面的代码为例,应该为:#include &stdio.h&#include &stdlib.h&#include &math.h&int main(){&&&&float x;&&&&while (1) {&&&&&&&&scanf("%f", &x);&&&&&&&&if (isinf(x)) {&&&&&&&&&&&&printf("It's infinite\n");&&&&&&&&}&&&&&&&&if (isnan(x)) {&&&&&&&&&&&&printf("It's NaN\n");&&&&&&&&}&&&&&&&&printf("x is %f, 0x%X\n", x, *(int*)&x);&&&&}&&&&return 0;}编译运行:infIt's infinitex is inf, 0x7F800000nanIt's NaNx is nan, 0x7FC00000其中isinf和isnan为C库提供的检测函数,分别用于检查infinite和NaN。而isnan实际上就是返回x != x,利用的就是NaN的特性,与任何数值进行相等比较都是返回false。所以当x != x时,即为NaN浮点值。
&script&window._bd_share_config={&common&:{&bdSnsKey&:{},&bdText&:&&,&bdMini&:&2&,&bdMiniList&:false,&bdPic&:&&,&bdStyle&:&0&,&bdSize&:&16&},&share&:{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg./static/api/js/share.js?v=.js?cdnversion='+~(-new Date()/36e5)];&/script&
阅读(160) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7661次
排名:千里之外
原创:90篇
转载:43篇
(1)(131)(1)c语言编译出错,提示非法使用浮点数?_百度知道}

我要回帖

更多关于 什么是浮点数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信