/***********2.91*************/
/*Compute |f|. If f is NaN, then return f.*/
float_bits float_absval(float_bits f)
{
unsigned sign = f >> 31;
unsigned exp = (f >> 23) & 0xFF;
unsigned frac = f &0x7FFFFF;
if(exp == 255 && frac)
{
return (sign << 31) | (exp << 23) | frac;
}
return (exp << 23) | frac;
}
/*************2.92***************/
/*Compute -f. If f is NaN, then return f. */
float_bits float_negate(float_bits f)
{
unsigned sign = f >> 31;
unsigned exp = (f >> 23) & 0xFF;
unsigned frac = f & 0x7FFFFF;
if(exp == 0xFF && frac)
{
return f;
}
return ((~sign & 1) << 31) | (exp << 23) | frac;
}
/************2.93***************/
/*Compute 0.5*f. If f is NaN,then return f. */
float_bits float_half(float_bits f)
{
unsigned sign = f >> 31;
unsigned exp = (f >> 23) & 0xFF;
unsigned frac = f & 0x7FFFFF;
if(exp == 0xFF)
{
return f;
}
if(exp == 0)
{
if((frac & 0x03) == 0x03)
{
frac = (frac >> 1) + 1;
}
else
{
frac = (frac >> 1);
}
}
else
{
exp--;
if(exp == 0)
{
if((frac & 0x03) == 0x03)
{
frac = ((frac >> 1) + 1) + (1 << 22);
}
else
frac = (frac >> 1) + (1 << 22);
}
}
return (sign << 31) | (exp << 23) | frac;
}
/***********2.94************/
/* Compute 2*f. If f is NaN, then return f. */
float_bits float_twice(float_bits f)
{
unsigned sign = f >> 31;
unsigned exp = (f >> 23) & 0xFF;
unsigned frac = f & 0x7FFFFF;
if(exp == 0xFF)
{
return f;
}
if(exp == 0)
{
if(frac & (1 << 22))
{
exp++;
frac = (frac - (1 << 22)) << 1;
}
else
{
frac = frac << 1;
}
}
else
{
exp++;
if(exp == 0xFF)
{
frac = 0;
}
}
return (sign << 31) | (exp << 23) | frac;
}
/*************2.95**************/
/* Compute (float) i */
float_bits float_i2f(int i)
{
unsigned sign;
unsigned exp;
unsigned frac;
int j;
if(i == 0)
{
return (unsigned)i;
}
//小于零的話符号位置1,取-i進行操作
if(i < 0)
{
i = ~i + 1;
sign = 1;
}
else
{
sign = 0;
}
//判斷非零的最高位,從第0位開始計,j為最高非零位(不計符号位)
for(j = 31;j > 0; --j)
{
if((0x01 << j) & i)
{
break;
}
}
//階碼位比較容易确定
exp = 127 + j;
//沒有精度溢出時
if(j <= 23)
{
frac = ((~(1 << j)) & i) << (23 - j);
}
//精度溢出時
else
{
//舍棄
if((((1 << (j - 23)) - 1) & i) < (1 << (j - 24)))
{
frac = ((~(1 << j)) & i) >> (j - 23);
}
//舍入
else if((((1 << (j - 23)) - 1) & i) > (1 << (j - 24)))
{
frac = ((~(1 << j)) & i) >> (j - 23);
frac = (frac + 1) & ~(1 << 23);
if(frac == 0)
{
exp++;
}
}
//向偶舍入
else
{
frac = ((~(1 << j)) & i) >> (j - 23);
if(frac & 0x01)
{
frac = (frac + 1) & ~(1 << 23);
if(frac == 0)
{
exp++;
}
}
}
}
return (sign << 31) | (exp << 23) | frac;
}
/************2.96**************/
/*
* Compute (int)f.
* If conversion causes overflow or f is NaN, return 0x80000000
*/
int float_f2i(float_bits f)
{
unsigned sign = f >> 31;
unsigned exp = (f >> 23) & 0xFF;
unsigned frac = f & 0x7FFFFF;
int result;
if(exp <= 126)
return 0;
else if(exp > 126 && exp <= 150)
{
frac = frac >> (150 - exp);
//如果是負數,要有一個取補碼的過程(關鍵一步),測試時可用0xc7ffffff測試
if(sign)
{
result =((1 << 23) >> (150 - exp)) | frac;
result = ~result + 1;
return (sign << 31) | result;
}
else
return (sign << 31) | ((1 << 23) >> (150 - exp)) | frac;
}
else if(exp > 150 && exp <= 157)
{
frac = frac << (exp - 150);
//如果是負數,則取補碼,測試時可用0xcdffffff測試
if(sign)
{
result = ((1 << 23) << (exp - 150)) | frac;
result = ~result + 1;
return (sign << 31) | result;
}
else
return (sign << 31) | ((1 << 23) << (exp - 150)) | frac;
}
else
{
return 0x80000000;
}
}