1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <limits.h>
#include <math.h>
#include "../code/data/show-bytes.c"
float my_u2f(unsigned int my_u) {
assert(sizeof(unsigned int) == sizeof(float));
union {
unsigned int u;
float f;
} my_union;
/* Apparently you cannot print the bytes of a float directly? like this printf("%x\n", f); */
my_union.u = my_u;
return my_union.f;
}
float fpwr2(int x)
{
/* Result exponent and fraction */
unsigned exp, frac;
unsigned u;
int k = 8;
int n = 23;
int bias = (1<<(k-1))-1;
int max_e = ((1<<k) - 2) - bias;
if (x < 1-bias-n) {
/* Too small. Return 0.0 */
exp = 0;
frac = 0;
} else if (x < 1-bias) {
/* Denormalized, [(1-bias-n), (1-bias)] [-139, -126] */
exp = 0;
frac = 1<<(x+1-bias-n);
} else if (x<=max_e) {
/* Normalized */
exp = x+bias;
frac = 0;
} else {
/* Too big. Return +oo */
exp = (1<<8)-1;
frac = 0;
}
/* Pack exp and frac into 32 bits */
u = (exp << 23) | frac;
/* Return as float */
return my_u2f(u);
}
int main(void) {
/* 2.90 */
printf("%f\n", fpwr2(-1)); /* 65536 */
printf("%f\n", fpwr2(16)); /* 65536 */
printf("%f\n", fpwr2(15)); /* 32768 */
printf("%f\n", fpwr2(14)); /* 16384 */
printf("%f\n", fpwr2(13)); /* 8192 */
printf("%f\n", fpwr2(12)); /* 4096 */
printf("%f\n", fpwr2(11)); /* 2048 */
printf("%f\n", fpwr2(10)); /* 1024 */
printf("%f\n", fpwr2(128));
return 0;
/* 2.91 */
printf("%x\n", 0b01000000010010010000111111011011);
/*
0 10000000 10010010000111111011011
E = 128-127 = 1
M = 1 + f
f = (2^22+2^19+2^16+2^11+2^10+2^9+2^8+2^7+2^6+2^4+2^3+2^1+2^0)/2^23
V = (2^E)(M)
13176795/4194304
22/7 = 2(1+f)
11/7 = (1+f)
4/7 = f
n = 0.yyy = f
n = Y/((1<<k) - 1)
n = 4/((1<<3) - 1)
0 10000000 [100]+
*/
show_float(22.0f/7.0f);
printf("%b\n", 0x40492492);
/* so we have 22/7
0 10000000 10010010010010010010010
and the approx
0 10000000 10010010000111111011011
at the 9th position the values diverge
*/
return 0;
/* 2.90 */
printf("%f\n", fpwr2(-1)); /* 65536 */
printf("%f\n", fpwr2(16)); /* 65536 */
printf("%f\n", fpwr2(15)); /* 32768 */
printf("%f\n", fpwr2(14)); /* 16384 */
printf("%f\n", fpwr2(13)); /* 8192 */
printf("%f\n", fpwr2(12)); /* 4096 */
printf("%f\n", fpwr2(11)); /* 2048 */
printf("%f\n", fpwr2(10)); /* 1024 */
printf("%f\n", fpwr2(128));
return 0;
}
|