核心思路:按照书上的分,符号位,exp段,frac段处理.
舍入也是按书上的来,把舍弃的部分与中值相比较.
舍入之前必须先把frac和exp合并在一块 根据舍弃的情况加一 这样加一如果frac段的进位进到了exp段就会加到exp段
#include <stdio.h>
#include <limits.h>
typedef unsigned float_bits;
float_bits float_i2f(int i);
unsigned bits_mask(int l);
int main()
{
int i= 2147483583;//这个数+1就会被舍入到INT_MAX;
printf("i2f=%x\n",float_i2f(i));
return 0;
}
unsigned bits_mask(int l) {
return (unsigned) -1 >> (32-l);
}
float_bits float_i2f(int i)
{
printf("i=%x\n",i);
int n=0;
int times=0;
unsigned mask=0x40000000;
unsigned sign = i >> 31;
unsigned exp = 0;
unsigned frac = 0;
unsigned num= (unsigned)i;//因为后面涉及到右移
if (i == 0) {
sign = 0;
exp = 0;
frac = 0;
return sign << 31 | exp << 23 | frac;
}
if (i == INT_MIN) {
sign = 1;
exp = 127 + 31;
frac = 0;
return sign << 31 | exp << 23 | frac;
}
if(sign){
num=~num+1;
}
num = num & 0x7fffffff;
//通过循环找到i的最高位.
while(n==0){
n = num & mask;//从31位开始取位
times++;
mask>>=1;
}
unsigned leng = 32-times;//得到参数i的二进制位数
exp = 127+leng-1;
if(leng<=24){//整数不长了 浮点数的frac的23位可以容纳
num = num<<(23-leng+1);
num = (exp << 23) |(num&0xff7fffff);//隐含第24位得1
}
else{//整数太长了,超过frac的23位
int move = leng-1-23;
unsigned round_part = num&bits_mask(move);
unsigned round_mid = 1<<(move-1);
num = (exp << 23) |((num>>move)&0xff7fffff);
if (round_part < round_mid) {
}
else if (round_part > round_mid)
num += 1;
else{
if ((num & 0x1) == 1)
num += 1;
}
}
return sign << 31 | num;
}
//https://www.h-schmidt.net/FloatConverter/IEEE754.html IEEE-754浮点转换器 用于检查结果
写了好几天了,断断续续写 参考了2.97 - CASPP 3e Solutions,建议一定要自己写一遍这个,这一题和书本内容紧密相连.