新浪博客

不使用强转,将float型数据转化成int型

2018-03-23 21:32阅读:
我们知道在c语言中有一个很强大的功能那就是强转,使用这一功能可以将各个类型进行相互转换。如果不使用强转,怎么将float型数据转化成int型呢。这里我们先要了解一下float型数据在内存中是如何摆放的。 不使用强转,将float型数据转化成int型
知道了摆放情况,接下来就是分析。我们在vs2012里面先声明一个float型变量f赋初始值为12.125。
不使用强转,将float型数据转化成int型

开始调试,取f的地址 0X00affaa8,查看内存
不使用强转,将float型数据转化成int型
不使用强转,将float型数据转化成int型
这时候我们就会发现0x00affaa8地址下保存的是十六进制的12.125值为0x41420000
为了知道符号位,我们就应该把0x41420000>>31,求出符号位。判断符号位是1还是0,这时声明一个标记变量sign用来保存判断结果,若为1,则sign=1
这时我们开始分离指数部分,按二进制在内存中的存储方式,指数位为8位二进制,
所以指数部分就是41。如何得到41?一样的套路,将0x41420000&0x7f800000就可以得到0x41000000,然后再>>23,然后减去127得到指数位的大小。判断指数位大小,分情况处理。
如果exp>0,那么所转换的数等于1<<exp(这里是因为科学计数法的缘故,尾数部分只有小数位,所以得自己加上1*2^exp。提出尾数部分,然后不停的取出原来整数位的数字。每次循环,让尾数<<1,k保存mag&0x7f800000的结果,看结果是否等于0,若等于k为1,若不等于k为0。返回的整型就等于k<<exp+初始i。如果sign等于1,则返回的整型为负数。
如果exp等于0,那么返回1,若sign等于1,则返回-1.
源代码如下:
#include
int ftoi(const float f)
{
int i=0;
int k;
int mag=0;
int exp=0;
int sign=0;
int num;
num=*(int *)&f;
if( num>>31)
{ //求出符号位为1还是为0
sign = 1;
}
exp= num & 0x7f800000; //求出指数大小
exp= exp >> 23;
exp = exp - 127;
if( exp > 0 )
{ //如果指数大于0则如下处理
i=1<<exp; //因为是科学计数表示法,尾数部分只有小数位,所以得自己加上1*2^exp
mag=num & 0x7fffff; //提出尾数部分
while(--exp>=0)
{ //从尾数中取出原来的整数位的数字
mag=mag<<1;
k=(( (mag&0x800000) != 0 )?1:0);
i+=k<<exp;
}
if(sign==1) //若原f是负数,则返回负整数值
i=-i;
}
if(exp == 0)
{
i=1; //若指数为0,则根据 sign 返回1或-1
if(sign==1)
i=-1;
}

return i;

}
int main()
ftoi(12.125);
return 0;
}
通过以上操作,我们完全可以位运算来进行强转的操作,但过程有些繁琐,虽然c语言的强转,用起来非常舒服,但给人一种不严谨的感觉,因为不管表达式的值怎样,系统都自动将其转为赋值运算符左部变量的类型。
转变后数据可能有所不同,在不加注意时就可能带来错误。 这确实是个缺点,也遭到许多人们批评。但不应忘记的是:c语言最初是为了替代汇编语言而设计的,所以类型变换比较随意。当然, 用强制类型转换是一个好习惯,这样,至少从程序上可以看出想干什么。---引用。

我的更多文章

下载客户端阅读体验更佳

APP专享