位运算函数实现float型变量取整数位

本文只考虑了IEEE规格化值的转换场景,非规格化值/无穷大/NaN 等情况未做考虑。

关于浮点数的表示,推荐阅读《CSAPP》第二章:信息的表示和处理。

=================

虽然C语言自带隐式类型转换,即:

float f=12.25;

int a=f;

printf("%d\n",a);    //结果是12

但是这几天了解了float的结构,所以自己写了一个函数  int  ftoi(const float f)  来实现它

下面是float的结构:

float一共32位,其结构定义如下:


|-------- 31 -------|------------ 30-23 ------------ |------------ 22-0 ------------|


   符号位(sign)         指数部分(exp)                     小数部分(mag)



sign:符号位就一位,0表示正数,1表示负数


exp: 指数部分长8位,无符号整数。

阶码 E=exp-Bias,阶码长度k=8的情况下,Bias=2^(8-1) - 1 = 127。

mag:小数部分,定点小数,小数点在最左边,隐含了一个小数点左侧的1。

小数M = 1 + mag。

整体上是以2进制的科学记数法来表达,即:

V = 2^E * M

那么要将整数位求出来,就必须分别提取出sign,exp,mag 三部分的二进制代码,所以使用位运算达成目标。

#include<stdio.h>
int  ftoi(const float f);

int ftoi(const float f){
	int i=0,mid_num,k,f_mag=0,f_exp=0,f_sign=0;
	mid_num=*(int *)&f; 	
	if( mid_num>>31){	           //求出符号位为1还是为0
		f_sign = 1;			
	}	
	
	f_exp = mid_num & 0x7f800000;  //求出指数大小	 
	f_exp = f_exp >> 23;
	f_exp = f_exp - 127;
	
	if( f_exp > 0 ){               //如果指数大于0则如下处理 
		i=1<<f_exp;	       //因为是科学计数表示法,尾数部分只有小数位,所以得自己加上1*2^f_exp		 
		f_mag=mid_num & 0x7fffff;  //提出尾数部分
		while(--f_exp>=0){         //从尾数中取出原来的整数位的数字
			f_mag=f_mag<<1;		
			k=(( (f_mag&0x800000) != 0 )?1:0);		
			i+=k<<f_exp;			
		}		
		if(f_sign==1)              //若原f是负数,则返回负整数值 
		   i=-i;		
	}
	if(f_exp == 0){
	    i=1;                //若指数为0,则根据 f_sign 返回1或-1 
		if(f_sign==1)
		   i=-1;
		}
	
	return i; 
	
}
int main(int argc,char *argv[]){
    float f;
    int i;
	scanf("%f",&f);
	i=ftoi(f);
	printf("ftoi(f)=%d\n",i);
		
	
	return 0;
}

关于非规格化数 / 无穷大 / NaN 等含义,建议参考csapp上的描述。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值