编写安全代码:小心使用浮点数
博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
#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.out Not equal!
而对于整数来说,如果不发生溢出的情况下,x*y/z是等于x*(y/z)。
#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.0000000001 < x && x < 0.0000000001) {printf("x is in 0 range!\n");}return 0; }
编译输出:
[fgao@fgao-vm-fc13 test]$ gcc -g test.c [fgao@fgao-vm-fc13 test]$ ./a.out x is in 0 range!
这两个都是比较常见的浮点陷阱,下面要说明的是浮点数值的两个exception
#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.out x is inf x is -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.out inf x is inf nan x 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; }
编译运行:
inf It's infinite x is inf, 0x7F800000 nan It's NaN x is nan, 0x7FC00000
其中isinf和isnan为C库提供的检测函数,分别用于检查infinite和NaN。而isnan实际上就是返回x != x,利用的就是NaN的特性,与任何数值进行相等比较都是返回false。所以当x != x时,即为NaN浮点值。
转载于:https://www.cnblogs.com/because/archive/2012/10/05/2711989.html
编写安全代码:小心使用浮点数相关推荐
- java云端开发_云端编写Java代码的方法
云端编写Java代码的方法 通常情况下,正如云厂商和虚拟计算提供商所宣传的转移到云端是一个无缝的流程,经验却告诉我们过于猛烈地脱离内部数据中心,部署到云端是一种复杂的方式.从部署流程到方式的所有事情, ...
- 第1课第4.4节_Android硬件访问服务编写HAL代码
android应用如何访问C库 - 落魄影子 - 博客频道 - CSDN.NET http://blog.csdn.net/ab198604/article/details/51249303 And ...
- html5编写网页代码_freeCodeCamp.org的未来-从向世界传授语言到编写代码的5年经验...
html5编写网页代码 freeCodeCamp went live in October 2014. In the five years since, we've done quite a bit. ...
- java培训教程分享:Java编写软件代码自动提示功能
本期的java培训教程分享主要是介绍的java编写软件代码的一个自动提示功能,很多零基础和初学java的同学们对这一块还不是很了解,Eclipse for android 实现代码自动提示智能提示功能 ...
- 编写单元测试代码遵守BCDE原则,以保证被测试模块的交付质量,那么下列说法正确的是
多选 编写单元测试代码遵守BCDE原则,以保证被测试模块的交付质量,那么下列说法正确的是:答案在文末 A. Border,边界值测试,包括循环边界.特殊取值.特殊时间点.数据顺序等. B. Corre ...
- 编写优质代码的 6 大关键方法
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自|机器学习实验室 [译者注]作为一名开发者,编写一手干净的 ...
- 如何优雅的编写 JavaScript 代码
几乎每个大一点公司都有一个"运行时间长,维护的工程师换了一批又一批"的项目,如果参与到这样的项目中来,大部分人只有一个感觉--"climb the shit mounta ...
- 你解决的问题比你编写的代码更重要!
软件的目的有时会被遗忘 程序员似乎忘记了软件的真正目的,那就是解决现实问题. 50年前,在1968年,由北约科学委员会主办的软件工程工作会议召开.那时,人们开始注意到软件正在成为社会的基本组成部分.然 ...
- java代码如何与界面联系在一起_如何在Visual Studio Code 中编写Java代码
本文将展示如何在Visual Studio Code中用Java编写和运行一个简单的Hello World程序. 首先您必须在本地开发环境中安装Java SE开发工具包(JDK) Visual Stu ...
- AppleWatch开发教程之Watch应用对象新增内容介绍以及编写运行代码
AppleWatch开发教程之Watch应用对象新增内容介绍以及编写运行代码 添加Watch应用对象时新增内容介绍 Watch应用对象添加到创建的项目中后,会包含两个部分:Watch App 和 Wa ...
最新文章
- android操作ui线程
- nginx 日志配置log_format用法
- 如何在FPGA设计环境中加时序约束 SDC (Z)
- 《MySQL必知必会》笔记--数据库基础
- springboot如何使用多线程,线程池管理
- VMware下安装Linux,Centos-7-x86_64-NetInstall.iso版本
- Spark SQL从入门到精通
- android 锁屏显示消息格式,通知!在锁屏上显示Android通知 | MOS86
- 小白共享网盘系统源码V5.0
- 迅雷软件测试报告总结范文,软件测试-实验三
- 《大数据分析技术》课程设计
- 如何将已有图片做成透明水印_如何给图片制作透明水印
- Julia数据可视化:Plots.jl包的使用
- 敏捷开发 — Story/Defect
- 嵌入式网络的基础知识 -- 数据包的组装、拆解、各头部格式
- 各位观众老爷不如点进来随便评论几句QUQ
- MIT多变量微积分--8.多元函数,等值面,偏导数,切平面逼近
- win11剪贴板数据如何删除 Windows清空剪贴板数据的步骤方法
- 大话设计模式十二:门面模式(牛市股票也会亏钱)
- Revit二次开发——扩展存储