本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第1章,建议4-2,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

建议4-2:浮点数转换为新类型时必须做范围检查

关于浮点类型数据的转换原则,在C99的6.3.1.4节与6.3.1.5节中做了非常重要的阐述,其表达的主要意思如下:
当我们将一个浮点类型的数据转换成除_Bool类型之外的一个整型数据时,该浮点数的小数部分须被丢弃,只保留它的整数部分。如果浮点数整数部分的值无法使用这种整型表示方法时,其行为是未定义的。
与此同时,如果我们将一个整数类型的数据转换成一个浮点类型时,如果该整型数据的值在该浮点数的取值范围内,并且能够被浮点类型精确表示,那么将会被正确转换;如果该整型数据的值在该浮点数的取值范围内,但不能够被浮点类型精确表示,那么转换的结果是最邻近的稍大或者稍小的可表示值;但如果该整型数据的值在该浮点数的取值范围外,其行为是未定义的。
当我们将一个double 类型降级转换为float类型、将long double类型降级转换到double或者float类型时,如果转换的值在新类型的取值范围内,并且能够被新类型精确表示,那么将会被正确转换;如果转换的值在新类型的取值范围内,但不能够被新类型精确表示,那么转换的结果是最邻近的稍大或者稍小的可表示值;但如果转换的值在新类型的取值范围外,其行为是未定义的。
由此可见,为了避免浮点数据转换时导致的未定义行为,我们应该在转换时对数据进行相关的范围检查。例如,下面的代码清单1-23演示了如何将double类型转换为int类型。

代码清单1-23 double转换为int类型示例
#include <stdio.h>
#include<limits.h>
int main(void)
{ double d1=2147483648.01;int i1=0;if(d1>(double)INT_MAX||d1<(double)INT_MIN){        }else{i1=(int)d1;}printf("i1=%d\n",i1);return 0;
}

在上面的程序中,我们通过语句“if(d1>(double)INT_MAX||d1<(double)INT_MIN)”来对程序做类型转换时的取值范围检查,这样就可以避免在执行语句“i1=(int)d1”时发生未定义行为。
但需要特别强调的是,上面的程序是建立在double类型的取值范围大于int类型的取值范围的基础之上的。因此,在使用这种方法做取值范围检查时,你必须完全明白不同编译器所对应的相关类型的取值范围。假设在某个编译器中,double类型的取值范围小于int类型的取值范围,那么上面这种方法将是不可行的,实际上这种情况基本没有。
相对于浮点数与整数之间的转换,浮点数与浮点数之间的转换就简单多了。演示示例如代码清单1-24所示。

代码清单1-24  double与float类型转换示例
#include <stdio.h>
#include<limits.h>
#include<float.h>
int main(void)
{ long double ld1=1.7976931348623158e+308;double d1=1.0;double d2=1.0;float f1=1.0f;float f2=1.0f;/*double->float*/if(d1>FLT_MAX||d1<FLT_MIN){    }else{f1=(float)d1;}/*long double->double*/if(ld1>DBL_MAX||ld1<DBL_MIN){}else{d2=(double)ld1;}/*long double->float*/if(ld1>FLT_MAX||ld1<FLT_MIN){}else{f2=(float)ld1;}return 0;
}

《编写高质量代码:改善c程序代码的125个建议》——建议4-2:浮点数转换为新类型时必须做范围检查...相关推荐

  1. 《编写高质量代码:改善c程序代码的125个建议》——建议4-1:整数转换为新类型时必须做范围检查...

    本节书摘来自华章计算机<编写高质量代码:改善c程序代码的125个建议>一书中的第1章,建议4-1,作者:马 伟 更多章节内容可以访问云栖社区"华章计算机"公众号查看. ...

  2. 读《编写高质量iOS与OS X代码的52个有效方法》

    又看了一遍<编写高质量iOS与OS X代码的52个有效方法>这本书,做一个简单的总结,其中runtime和GCD那些的不是太详细,要想很详细估计写的东西比篇文字都多,但恰巧又是iOS的重点 ...

  3. 如何编写高质量和可维护的代码

     如何编写高质量和可维护的代码 我们怎么做才能既不需要写很多注释,又能保证代码易于理解呢? 其中一个主要的方法就是让代码自文档化.其优势在于,既不用写注释,又能使得代码易于维护. 下面就是三种使得 ...

  4. [读书笔记]读《Effective Objective-C 2.0编写高质量iOS与OS X代码的52个有效方法》(一)...

    第一条:了解Objective-C 语言的起源 Objective-C为C语言添加了面向对象特性,是其超集.Objective-C使用动态绑定的消息结构,也就是说,在运行时才会检查对象类型.接收一条消 ...

  5. 《Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》笔记

    2019独角兽企业重金招聘Python工程师标准>>> 这本书很早有了解过,评价都不错,但最近才终于把这本书看完,整本书介绍了很多个提高Objective-C的方法,都是平时用得很多 ...

  6. 【Python】使用31条规则编写高质量且美丽的Python代码

    Raymond Hettinger在pycon US 2013 视频,幻灯片上的讲话. 代码示例和直接引用都来自Raymond的演讲.我在这里复制它们是为了我自己的启发和希望别人会发现它们像我一样方便 ...

  7. Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法笔记-协议与分类...

    23.通过委托与数据源协议进行对象间通信 如果要在委托对象上调用可选方法,那么必须提前使用类型信息查询方法判断这个委托对象能否响应相关选择子. if ( [_delegate respondsToSe ...

  8. 编写高质量代码改善C#程序的157个建议——建议148:不重复代码

    建议148:不重复代码 如果发现重复的代码,则意味着我们需要整顿一下,在继续前进. 重复的代码让我们的软件行为不一致.举例来说,如果存在两处相同的加密代码.结果在某一天,我们发现加密代码有个小Bug, ...

  9. 编写高质量代码改善C#程序的157个建议——建议86:Parallel中的异常处理

    建议86:Parallel中的异常处理 建议85阐述了如何处理Task中的异常.由于Task的Start方法是异步启动的,所以我们需要额外的技术来完成异常处理.Parallel相对来说就要简单很多,因 ...

最新文章

  1. 异常分析 (空间太小)
  2. vue 导入公共css_HTML+CSS入门 vue引入通用CSS
  3. Linux+pycharm下 安装tensorflow时遇到的bug
  4. Codeforces第一次rated比赛
  5. python学习笔记9-函数1
  6. java SWT Browser实现浏览器功能并运行JavaScript代码
  7. AI 又进阶!除了鉴别 PS 图片,还能一键卸妆!
  8. 【论文写作】JSP在线考试系统如何写功能描述
  9. openssl校验SSL证书public key是否配对
  10. python socket 接口
  11. HR,是该做一个Excel仪表盘了!
  12. 【转】C#实现SqlServer数据库的备份和还原
  13. Django表单系统
  14. IXI MEGA声卡M4 6 8 PIUS M2 M-NU2 NU4安装调试教程
  15. Note Of Effective C++ 、More Effective C++ And Effective Modern C++
  16. VBA批量导入图片到多Word文档并加标题(会飞的鱼)
  17. 沐阳JP1081B USB转网口 内核选项
  18. 网页设计(三)——JavaScript
  19. (转)如何成为一名优秀的程序员?
  20. 2021-MAXP-DGL图机器学习大赛-Graph@ICT-复盘与总结【rank6】

热门文章

  1. VS设置程序启动权限为管理员权限
  2. [最短路/线段树大法优化DIJ] 【模板】单源最短路径(标准版)
  3. CODE[VS] 2824 盗窃-大海的奇迹
  4. jstl fmt:formatNumber 数字货币格式化
  5. vs2013 git 使用总结
  6. 反射的妙用-类名方法名做参数进行方法调用实例demo
  7. 详解自然语言处理5大语义分析技术及14类应用(建议收藏)
  8. 零基础入门Python I/O:从print函数开始
  9. Simulink之大功率晶体管(GTR)
  10. FreeRTOS队列集