#include <stdio.h>
2#include <stdlib.h>
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
39
40 return 0;
41}、
其实对于内存上所保存的数据是没有具体类型的,所谓数据类型仅仅只是以怎样一种方式进行数据的访问罢了,我们通过指针来进行访问就很好的说明了这个问题,例如int *ptr,表示ptr所指向的地址以int类型进行访问,如果把ptr改为float类型即float *ptr,其便以float类型来访问地址所对应的内存。
既然像第二小节说的float类型的参数保存区无法修改了,那么我们就想办法直接绕过float类型来进行数据访问。
参考demo:
1#include <stdio.h>
2#include <stdlib.h>
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
30
31 return 0;
32}
分析一下:
Demo中通过两个宏进行地址的类型处理转化,对float内存进行直接访问来保存整形数据,同样后面通过地址的直接访问来获得整形数据,这样就可以绕开float类型的处理问题。
同时大家也要注意其本地类型占用字节大小(float)需>=所要转化的类型占用字节大小(int),否则会造成数据的篡改,这样就会造成更多麻烦。
其实这里仅仅只用float进行存储参数的设计,原本就存在设计上的缺陷,可以通过共联体,或者无类型内存设计方案进行处理,这样就不会出现类似的问题了。
|