c语言浮点型与整形比较大小,C语言整形与浮点型转化过程中的精度损失
本篇文章主要解决的问题是C语言整形与浮点型转化过程中的精度损失从而容易产生bug,对于浮点和整形的相关内容大家可以参考下面两篇文章、,这里就不再赘叙了。
1整形与浮点转化的精度损失参考小程序:1#include
2#include
3
4/*************************************
5 * Fuction:精度损失
6 * Author : (公众号:最后一个bug)
7 ************************************/
8 int main(int argc, char *argv[]) {
9 float fVal1 = 0;
10 int sVal1 = 60012502;
11 int sVal2 = 60012501;
12
13 printf("sizeof(int) = %d\n",sizeof(int));
14 printf("sizeof(float) = %d\n",sizeof(float));
15
16 fVal1 = (float) sVal1;
17 printf("fVal1 = %f\n",fVal1);
18
19 fVal1 = (float) sVal2;
20 printf("fVal1 = %f\n",fVal1);
21
22
23 sVal1 = (int) fVal1;
24 printf("sVal1 = %d\n",sVal1);
25
26 sVal2 = (int) fVal1;
27 printf("sVal2 = %d\n",sVal2);
28
29 if(sVal1 == sVal2)
30 {
31 printf("sVal1 == sVal2\n");
32 }
33 else
34 {
35 printf("sVal1 != sVal2\n");
36 }
37
38 printf("公众号:最后一个bug\n");
39
40 return 0;
41}运行结果:
微信图片_20200802232806.png (7 KB, 下载次数: 1)
2020-8-2 23:30 上传分析一下:我只想说真的牛,转来转去竟然使得两个不一样的数相等了,所以大家在平时的项目中进行强制类型转化可要慎重考虑下了。
其发生该情况的主要原因是由于4字节float类型变量不能完全覆盖int类型的所有类型数值,所以在进行强制类型转化的过程中会产生精度上的损失,这样大家稍不留意就会有一些不必要的麻烦。
2没必要强制转化的地方
大家对数据进行强制类型转化很大部分都是为了方便计算,比如通过AD采样获得的数据都是整形的数据,通过比例因子处理以后成为了浮点数据,然后通过浮点进行计算实在是再方便不过了。
对于上面这种强制类型转化情景是值得考虑的,可是对于下面的场景就没有必要了,反而容易出现问题。
微信图片_20200802232810.png (16.34 KB, 下载次数: 2)
2020-8-2 23:30 上传
对于上面这种处理情景,估计很多小伙伴就直接通过整形接受到数据,然后强制类型转化为了浮点类型进行保存,当需要使用到该参数的时候,又通过把该浮点存储保存的值强制类型转化为整形,最后再进行整形参数的相关处理。
经过这样整形-->浮点-->整形的处理,如果你拿着最后的整形进行数据判断,就很大概率上会存在类似于前面的Demo程序那样存在bug。
那么有一些小伙伴该问了,为什么不用整形存储呢 ? 用整形存储不就没这个问题了吗 ?当你真正进入工作岗位,可能某一天一个同事离职,把一堆摊子丢给你了,然而里面的数据结构等等处理,不是不想动,而是不敢动,往往新接手的代码把控能力有有限,可能不小心的参数配置都会导致程序奔溃,还真不敢大动作?所以还是技巧性的填好坑,等待下一次重构的机会。
3处理小技巧
其实对于内存上所保存的数据是没有具体类型的,所谓数据类型仅仅只是以怎样一种方式进行数据的访问罢了,我们通过指针来进行访问就很好的说明了这个问题,例如int *ptr,表示ptr所指向的地址以int类型进行访问,如果把ptr改为float类型即float *ptr,其便以float类型来访问地址所对应的内存。
既然像第二小节说的float类型的参数保存区无法修改了,那么我们就想办法直接绕过float类型来进行数据访问。参考demo:1#include
2#include
3
4/*************************************
5 * Fuction: 两个宏--可以继续扩展
6 * Author : (公众号:最后一个bug)
7 ************************************/
8#define SET_INT_VAL(addr,val) *((int*)(&addr)) = val
9#define SET_GET_VAL(addr) *((int*)(&addr))
10
11/*************************************
12 * Fuction: 改善小技巧
13 * Author : (公众号:最后一个bug)
14 ************************************/
15 int main(int argc, char *argv[]) {
16 float fVal1 = 0;
17 int sVal1 = 60012502;
18
19 printf("sizeof(int) = %d\n",sizeof(int));
20 printf("sizeof(float) = %d\n",sizeof(float));
21
22 //接受整形数据到float数据内存
23 SET_INT_VAL(fVal1,sVal1);
24
25 //float数据内存获得整形数据
26 printf("SET_GET_VAL(fVal1) = %d\n",SET_GET_VAL(fVal1));
27 printf(" sVal1 = %d\n",sVal1);
28
29 printf("公众号:最后一个bug\n");
30
31 return 0;
32}
运行结果:
微信图片_20200802232819.png (6.8 KB, 下载次数: 1)
2020-8-2 23:30 上传分析一下:Demo中通过两个宏进行地址的类型处理转化,对float内存进行直接访问来保存整形数据,同样后面通过地址的直接访问来获得整形数据,这样就可以绕开float类型的处理问题。
同时大家也要注意其本地类型占用字节大小(float)需>=所要转化的类型占用字节大小(int),否则会造成数据的篡改,这样就会造成更多麻烦。
其实这里仅仅只用float进行存储参数的设计,原本就存在设计上的缺陷,可以通过共联体,或者无类型内存设计方案进行处理,这样就不会出现类似的问题了。
4、最后小结
今天主要是跟大家分享了一个小案例,大家好好理解下,C语言虽然语法不多,不过想要写出好的C代码并非易事,需要多练多悟!作者也会慢慢回顾这些年的编程经验并分享给大家。
c语言浮点型与整形比较大小,C语言整形与浮点型转化过程中的精度损失相关推荐
- 如何用C语言改变宏定义的大小,C语言中宏定义使用的小细节
C语言中宏定义使用的小细节 #pragma#pragma 预处理指令详解 在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#p ...
- c 语言比较三个整数大小,C 语言 —— 比较三个整数的大小并从大到小输出
思路一:定义两个比较大小的函数,依次两两比较输出最大或最小的数字(较为繁琐,最易分析) /* C 语言比较三个整数的大小并从大到小输出 思路:定义两个比较大小的函数,依次两两比较输出最大或最小的数字 ...
- C语言zh字符串指针的大小,C语言的一些小技巧,小知识
1.用if(!strcmp(s1, s2)) 比较两个字符串等值,是否是个好风格? 这并不是个很好的风格, 虽然这是个流行的习惯用法.如果两个字符串相等, 这个测试返回为真, 但! ("非& ...
- c语言 类void 方法 字节大小,C 语言数据类型
C 语言数据类型 在本教程中,您将学习C编程中的基本数据类型,例如int,float,char等. 在C语言中有以下数据类型:类型数据类型 基本数据类型int, char, float, double ...
- c语言指针如何增加内存大小,C语言如何给指针分配内存?
匿名用户 1级 2010-09-20 回答 看了下,基本上回答的都是用new 那个,都是C++程序员吧 c语言里面是用malloc的 写了个简单程序,看看是不是楼主需要的 #include #incl ...
- c语言比两个人年龄大小,c语言结构体
满意答案 1234567891011121314151617181920212223242526272829303132333435#include<stdio.h>#include< ...
- c语言负数与正数判断大小,c语言编程,输入一些整数,判断其中正数与负数的个数,并分别求出正数与负数的平均值...
代码如下: #include "stdio.h" main( ) { int i,iNum,iCount1=0,iCount2=0,iCount3=0; for(i=1;i< ...
- c语言快速复数的比较大小,c语言中的复数操作
c语言中的复数操作 发布时间:2020-06-17 14:23:06 来源:亿速云 阅读:391 作者:鸽子 复数在数学运算中十分重要,在编写数值运算或者算法的时候,我们会用到复数这种概念. 那么,复 ...
- c语言三个字母比较大小,C语言stricmp()函数:比较两个字符串大小
函数名: stricmp 头文件: 函数原型: int stricmp(const char *str1, const char *str2); 功 能: 比较两个字符串大小,但不区分大小写 参 数: ...
最新文章
- 自从学了这套框架,自动化+性能都解决了
- Struts2 - 上传任意多个文件
- fastjson 1.1.71.android 版本发布,优化部分场景性能
- DayDayUp之Job:牛客网—算法工程师—剑指offer之66道在线编程(解决思路及其代码)——1~20
- Divan and a New Project 贪心,模拟(1000)
- hdu 1418 抱歉 (欧拉公式)
- [网络安全自学篇] 三十.文件上传漏洞、编辑器漏洞和IIS高版本漏洞及防御(三)
- JavaScript对象及初始面向对象
- 删除数据清理oracle表空间,oracle数据库删除无用表空间及数据文件过程
- windows server 2012安装
- 关于framework4.5的相关介绍
- pymysql模块的使用
- 受新冠病毒影响,谷歌延迟发布 Chrome 和 Chrome OS 安全更新版本
- 程序猿生存定律--表达背后的力量(1)
- IPSEC 004 ---- 模板海纳百川,不定对端有容乃大
- Debian系统关闭iptables的conntrack跟踪
- 华为交换机重制_华为交换机如何初始化?华为交换机初始化配置-百度经验
- PCA降维算法的原理及应用
- html5 img圆角,用 CSS3 给 图片添加圆角
- Spring+SpringMVC+Mybatis(开发必备技能)04、mybatis自动生成mapper_dao_model(包含工具与视频讲解) 纯绿色版本、配套使用视频,100%运行成功
热门文章
- CSP2019 游记
- C++结构体复制的相关问题
- HTML5期末大作业:麦路客电子网站设计——麦路客电子购物商城(37页) HTML5期末考核大作业,网站——购物商城
- C语言实现环形缓冲区
- pycharm忽略警告和恢复警告设置
- 清纯非主流_陕南赤子_新浪博客
- 古堡仙境,欧洲最美最著名的十大城堡
- CVPR 2023 | 65.4 AP!刷新COCO目标检测记录!InternImage:基于可变形卷积的大规模视觉基础模型...
- 图文传授win10系统设置临时环境变量的方法
- 被P8大佬面试2小时,差点干趴下了!