2018-2019-1 20165205 ch02 课下作业

ch02 课下作业

2.96

代码

#include <stdio.h>
#include <stdlib.h>
typedef unsigned float_bits;
float u2f(unsigned x){
return *((float*)&x);
}

int float_f2i(float_bits f){
unsigned sign = f>>31;
int exp = (f>>23) & 0xFF;
int frac = (f&0x7FFFFF) | (1<<23);
exp -= 127;
if(exp < 0) return 0;
if(exp >= 31) return 0x80000000; //绝对值不大于2^31(1<<31)
if(exp > 23) frac <<= (exp - 23);
else frac >>= (23 - exp);
return sign? -frac : frac;
}

void main(){
int x = 0;
do{
int m = float_f2i(x);
int n = (int)u2f(x);
if(m != n){
printf("error in %x:  %d %d
", x, m, n);
return;
}
x++;
}while(x!=0);
printf("Test OK
");
}
  • 利用循环做测试,但这个循环耗时很久
    测试结果:

2.97

代码

#include <stdio.h>
#include <stdlib.h>
typedef unsigned float_bits;
unsigned f2u(float f){
    return *((unsigned*)&f);
}
int is_float_equal(float_bits f1, float f2){
    return f2u(f2) == f1;
}

float_bits float_i2f(int i)
{
    if(i == 0) return 0;
    unsigned x = i>0?i:-i;
    int sign = i>0?0:1;
    int w = sizeof(int)<<3;
    int j;
    for(j=w-1; j>=0; j--){ //找到最高位
        if( (x>>j) & 1) break;
    }
    unsigned bias = 127;
    unsigned exp, frac;
    exp = bias + j;
    if(j <= 23) frac = x<<(23-j);
    else {
        frac = x>>(j-23);
        unsigned mask = (1<<(j-23)) - 1;
        if( (x&mask) > (1<<(j-24)) ) frac++; //需要舍入	到大值
        else if( (x&mask) == 1<<(j-24)  &&  (frac&1)) 	frac++; //舍入到偶数
        if(frac == (1<<24)) exp++; //舍入到偶数超过	(1<<24) - 1,指数需要再加1
    }
    return sign<<31 | exp<<23 | frac&0x7FFFFF;
	}

void main(){
	int x = 0;
	do{
	    float_bits fb = float_i2f(x);
	    float ff = (float)x;
	    if(!is_float_equal(fb, ff)){
	        printf("error in %d:  %x %x
", x, fb, f2u	(ff));
	        return;
	    }
	    x++;
	}while(x!=0);
	printf("Test OK
");
}

测试结果:

小结:本次作业我刚开始看到并不会做,然后开始上网查,开始是直接查到了代码,然后发现我其实是看不懂别人写的代码的,比如将x左移31位,又比如和0xFF按为与去获得前八位等,这些我都慢慢尝试去看懂,当然最后也得到了自己想要的结果,包括这个作者的测试方法,直接用整数x,自增之后移位的方法,也让我受益颇多。
原文地址:https://www.cnblogs.com/mushroomissmart/p/9733685.html