2019年9月22日
题目2.88


答案
|
格式A |
格式B |
||
|
位 |
值 |
位 |
值 |
|
1 01110 001 |
-9/16 |
1 0110 0010 |
-9/16 |
|
0 10110 101 |
+208 |
0 1110 1010 |
+208 |
|
1 00111 110 |
-7/(2^10) |
1 0000 0111 |
-7/(2^10) |
|
0 00000 101 |
5/(2^17) |
0 0000 0000 |
+0 |
|
1 11011 000 |
-2^12 |
1 1111 0000 |
-∞ |
|
0 11000 100 |
+768 |
0 1111 0000 |
+∞ |
特殊要求
题目2.94
我的float_twice函数
1 /* Access bit-level representation floating-point number*/
2 typedef unsigned float_bits;
3
4 /* Compute 2*f. If f is NaN, then return f.*/
5 float_bits float_twice(float_bits f){
6 /* Decompose bit representation into parts */
7 unsigned sign = f&(1<<31);
8 unsigned exp = f&(0xFF<<23);
9 unsigned frac = f&0x7FFFFF;
10 // 特殊值:f = NaN or f = +-inf, 返回f本身
11 if(exp == (0xFF<<23)) return f;
12 // 非规格化:2.0*(float)f与2*(unsigned)f的低31位的位级表示一样
13 else if(!exp) return sign | (frac<<1);
14 // 最大的一些规格化:2.0*f溢出, 返回+-inf
15 else if(exp == (0xFE<<23)) return sign | (0xFF<<23);
16 // 其他的规格化:exp位+1
17 else return sign | (exp+(1<<23)) | frac;
18 }
我的测试函数
1 //测试函数
2 void MyTestFunc(float f){
3 //f = sqrt(-1); //本句用于测试f=NaN的情况
4 //unsigned f3 = 0x7f400000; f = *(float*)&f3; //本句用于测试2.0*f溢出的情况
5 float f2 = 2.0*f;
6 float_bits _f = *(unsigned*)&f,
7 _f2 = *(unsigned*)&f2,
8 flt_f = float_twice(_f);
9 printf("f = %f = 0x%.8x\n", f, _f);
10 printf("2.0*f = %f = 0x%.8x\n", f2, _f2);
11 printf("float_twice(f) = 0x%.8x\n", flt_f);
12 printf("(2.0*f == float_twice(f)) = %d\n\n", _f2 == flt_f);
13 return;
14 }
完整程序代码
1 #include <cstdio>
2 #include <cmath>
3 using namespace std;
4
5 /* Access bit-level representation floating-point number*/
6 typedef unsigned float_bits;
7
8 /* Compute 2*f. If f is NaN, then return f.*/
9 float_bits float_twice(float_bits f){
10 /* Decompose bit representation into parts */
11 unsigned sign = f&(1<<31);
12 unsigned exp = f&(0xFF<<23);
13 unsigned frac = f&0x7FFFFF;
14 // 特殊值:f = NaN or f = +-inf, 返回f本身
15 if(exp == (0xFF<<23)) return f;
16 // 非规格化:2.0*(float)f与2*(unsigned)f的低31位的位级表示一样
17 else if(!exp) return sign | (frac<<1);
18 // 最大的一些规格化:2.0*f溢出, 返回+-inf
19 else if(exp == (0xFE<<23)) return sign | (0xFF<<23);
20 // 其他的规格化:exp位+1
21 else return sign | (exp+(1<<23)) | frac;
22 }
23
24 //测试函数
25 void MyTestFunc(float f){
26 //f = sqrt(-1); //本句用于测试f=NaN的情况
27 //unsigned f3 = 0x7f400000; f = *(float*)&f3; //本句用于测试2.0*f溢出的情况
28 float f2 = 2.0*f;
29 float_bits _f = *(unsigned*)&f,
30 _f2 = *(unsigned*)&f2,
31 flt_f = float_twice(_f);
32 printf("f = %f = 0x%.8x\n", f, _f);
33 printf("2.0*f = %f = 0x%.8x\n", f2, _f2);
34 printf("float_twice(f) = 0x%.8x\n", flt_f);
35 printf("(2.0*f == float_twice(f)) = %d\n\n", _f2 == flt_f);
36 return;
37 }
38
39 int main() {
40 float f;
41 while(printf("please enter a float : ")){
42 scanf("%f", &f);
43 MyTestFunc(f);
44 }
45 return 0;
46 }
测试结果(输入输出都放在一起啦)
(1)f = NaN
please enter a float : 0 f = nan = 0xffc00000 2.0*f = nan = 0xffc00000 float_twice(f) = 0xffc00000 (2.0*f == float_twice(f)) = 1
(2)2.0*f = +-inf (溢出)
please enter a float : 0 f = 255211775190703847597530955573826158592.000000 = 0x7f400000 2.0*f = inf = 0x7f800000 float_twice(f) = 0x7f800000 (2.0*f == float_twice(f)) = 1
(3)一般情况
please enter a float : 0 f = 0.000000 = 0x00000000 2.0*f = 0.000000 = 0x00000000 float_twice(f) = 0x00000000 (2.0*f == float_twice(f)) = 1 please enter a float : 9999999999999999999999999999999999999999 f = inf = 0x7f800000 2.0*f = inf = 0x7f800000 float_twice(f) = 0x7f800000 (2.0*f == float_twice(f)) = 1 please enter a float : -302.34 f = -302.339996 = 0xc3972b85 2.0*f = -604.679993 = 0xc4172b85 float_twice(f) = 0xc4172b85 (2.0*f == float_twice(f)) = 1
题目2.97
我的float_i2f()函数
1 /* Access bit-level representation floating-point number*/
2 typedef unsigned float_bits;
3
4 /* Compute Exponent, the highest bit with value 1*/
5 int ComExp(unsigned i){
6 for(int E=31; E>=0; --E)
7 if(i & (1<<E))
8 return E;
9 printf("something wrong with cal_E()\n");
10 return -1; //abs = 0
11 }
12
13 /* Compute Fraction, with rounding to even*/
14 unsigned ComFrac(unsigned i, unsigned E){
15 i = i&((1<<E)-1);//delete highest bit with value 1
16 //no rounding
17 if(E <= 23)
18 return i<<(23-E);
19 //with rounding
20 else{
21 bool guard_bit = (i>>(E-23))&1,
22 round_bit = (i>>(E-24))&1,
23 sticky_bit = E>24 && (i&((1<<(E-24))-1));
24 //round up: >0.5
25 if(round_bit && sticky_bit) return (i>>(E-23))+1;
26 //round to even: =0.5
27 else if(round_bit && !sticky_bit && guard_bit) return (1>>(E-23))+1;
28 //round down: =0.5 or <0.5
29 else return i>>(E-23);
30 }
31 }
32
33 /* Compute (float)i*/
34 float_bits float_i2f(int i){
35 //i == 0
36 if(!i) return 0;
37 //i != 0
38 unsigned sign = i & (1<<31);//sign bit
39 unsigned iabs = sign ? -i : i;//absolute value of i
40 int E = ComExp(iabs);//exponent
41 unsigned exp = (E + 127) << 23;//exponent bits
42 unsigned frac = ComFrac(iabs, E);//fraction bits
43 //rounding makes exp++
44 if(frac & (1<<23)){
45 frac = 0;
46 exp += 1<<23;
47 }
48 return sign | exp | frac;
49 }
我的测试函数
1 //测试函数
2 void MyTestFunc(int i){
3 float f = (float)i;
4 float_bits _f = *(unsigned*)&f;
5 printf("i = %d = 0x%.8x\n", i, i);
6 printf("(float)i = %f = 0x%.8x\n", f, _f);
7 printf("float_i2f(i) = 0x%.8x\n", float_i2f(i));
8 printf("(float)i == float_i2f(i) = %d\n\n", _f == float_i2f(i));
9 return;
10 }
完整程序代码
1 #include <cstdio>
2 using namespace std;
3
4 /* Access bit-level representation floating-point number*/
5 typedef unsigned float_bits;
6
7 /* Compute Exponent, the highest bit with value 1*/
8 int ComExp(unsigned i){
9 for(int E=31; E>=0; --E)
10 if(i & (1<<E))
11 return E;
12 printf("something wrong with cal_E()\n");
13 return -1; //abs = 0
14 }
15
16 /* Compute Fraction, with rounding to even*/
17 unsigned ComFrac(unsigned i, unsigned E){
18 i = i&((1<<E)-1);//delete highest bit with value 1
19 //no rounding
20 if(E <= 23)
21 return i<<(23-E);
22 //with rounding
23 else{
24 bool guard_bit = (i>>(E-23))&1,
25 round_bit = (i>>(E-24))&1,
26 sticky_bit = E>24 && (i&((1<<(E-24))-1));
27 //round up: >0.5
28 if(round_bit && sticky_bit) return (i>>(E-23))+1;
29 //round to even: =0.5
30 else if(round_bit && !sticky_bit && guard_bit) return (1>>(E-23))+1;
31 //round down: =0.5 or <0.5
32 else return i>>(E-23);
33 }
34 }
35
36 /* Compute (float)i*/
37 float_bits float_i2f(int i){
38 //i == 0
39 if(!i) return 0;
40 //i != 0
41 unsigned sign = i & (1<<31);//sign bit
42 unsigned iabs = sign ? -i : i;//absolute value of i
43 int E = ComExp(iabs);//exponent
44 unsigned exp = (E + 127) << 23;//exponent bits
45 unsigned frac = ComFrac(iabs, E);//fraction bits
46 //rounding makes exp++
47 if(frac & (1<<23)){
48 frac = 0;
49 exp += 1<<23;
50 }
51 return sign | exp | frac;
52 }
53
54 //测试函数
55 void MyTestFunc(int i){
56 float f = (float)i;
57 float_bits _f = *(unsigned*)&f;
58 printf("i = %d = 0x%.8x\n", i, i);
59 printf("(float)i = %f = 0x%.8x\n", f, _f);
60 printf("float_i2f(i) = 0x%.8x\n", float_i2f(i));
61 printf("(float)i == float_i2f(i) = %d\n\n", _f == float_i2f(i));
62 return;
63 }
64
65 int main() {
66 int i;
67 while(printf("please enter an integer with hexadecimal notation : ")){
68 scanf("%x", &i);
69 MyTestFunc(i);
70 }
71 return 0;
72 }
测试结果(输入输出都放在一起啦)
please enter an integer with hexadecimal notation : 0 i = 0 = 0x00000000 (float)i = 0.000000 = 0x00000000 float_i2f(i) = 0x00000000 (float)i == float_i2f(i) = 1 please enter an integer with hexadecimal notation : -1 i = -1 = 0xffffffff (float)i = -1.000000 = 0xbf800000 float_i2f(i) = 0xbf800000 (float)i == float_i2f(i) = 1 please enter an integer with hexadecimal notation : fffffff i = 268435455 = 0x0fffffff (float)i = 268435456.000000 = 0x4d800000 float_i2f(i) = 0x4d800000 (float)i == float_i2f(i) = 1 please enter an integer with hexadecimal notation : 7fffffff i = 2147483647 = 0x7fffffff (float)i = 2147483648.000000 = 0x4f000000 float_i2f(i) = 0x4f000000 (float)i == float_i2f(i) = 1
明天又是新的一周,一起加油w!


