float_neg
求浮点数的相反数
#include <stdio.h>
unsigned float_neg(unsigned uf){
if((((uf>>23)&0xff)^0xff)||!(uf&((1<<23)-1))){
uf=(1<<31)^uf;
}
return uf;
}
int main(){
printf("0x%x",float_neg(0x0f000000));
}
解释:这里求浮点数取负,我们需要知道特殊的值NaN(无穷),所以只要排除掉NaN的情况我们就可以直接改变符号位来取负。
回想一下NaN的特点:阶码字段全为1,而小数字段非零。
uf>>23将小数字段舍去看阶码,((uf>>23)&0xff),用异或 可以知道如果阶码全为1则为0, 反之为1
然后我们再来看小数字段,(1<<23)到小数最高位的左一位,-1得到与小数字段对应的区域。通过与小数字段 与 就能知道是否小数字段非零。
所以如果它是一个NaN则直接return;否则就要进入条件语句。
最后我们改变符号位是的结果取负。
23位到30位为阶码字段,小数字段为0位到23位。
float_twice函数
求一个浮点数的两倍
因为浮点数的规格化数的乘法与非规格化数的乘法不是一个规则,所以我们要条件判断;
如果阶码字段为0,则为非规格化数,我们需要乘 2 就只能左移补位(注意不要改变符号位,补上符号位)。
如果阶码字段不为0,又 分为规格化数与 NaN无穷数。对于NaN我们直接return;对于规格化数,我们在阶码字段加1即可。
#include <stdio.h>
unsigned float_twice(unsigned uf){
if((uf&0x7f800000)==0)
uf=((uf&0x007fffff)<<1)|((uf&0x80000000));
else if((uf&0x7f800000)!=0x7f800000){
uf=uf+800000;
}
return uf;
}
int main(){
printf("0x%x",float_twice(0x11000001));
}