-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfloatbits.c
More file actions
211 lines (189 loc) · 5.6 KB
/
floatbits.c
File metadata and controls
211 lines (189 loc) · 5.6 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
* floatbits.c
* CSCI 247, Lab exercise 4, Fall, 2017
*
* Alexandra Puchko, October, 2017
*
*/
#include<stdio.h>
/* access bit-level representation of a floating-point number */
typedef unsigned float_bits;
/*
float_class identifies the class of floating-point number represented by a float_bits parameter
returns:
- negative integer, if the floating-point number is a “special” (±∞, or NaN)
- 0, if the floating-point number is denormalized
- positive integer, if the floating-point number is normalized
*/
int float_class(float_bits f){
//set default value to a number as a normalized
int fb_class = 1;
//calculate mask
int expr0 = (0xff << 8) | 0xff; //0xffff
int expr2 = (0x7f << 8) | 0xff; //0x7fff
//mask to set MSB as a 0
int mask1 = (expr2 << 16)| expr0; //0x7fffffff
//set MSB to 0
int expr = f & mask1;
int f_exp = expr >> 23;
if(!f_exp){
fb_class = 0;
} else if(!(f_exp ^ 0xff)){
fb_class = -1;
}
return fb_class;
}
/*
function which negates a floating-point number
returns:
- -f, if floating point number is not NaN
- f, if floating point number is NaN
*/
float_bits float_negate(float_bits f){
unsigned negate_fb = f;
// check if NaN
int expr0 = (0xff << 8) | 0xff; //0xffff
int expr2 = (0x7f << 8) | 0xff; //0x7fff
// set MSB to 0
int mask1 = (expr2 << 16)| expr0; //0x7fffffff
int expr = f & mask1;
// get exp_part
int f_exp = expr >> 23;
// get frac_part
int mask2 = (0x7f << 8) | 0xff;
mask2 = (mask2 << 8) | 0xff; //0x7fffff
int f_frac = f & mask2;
// check if f is NaN (first check exponent and then fractional part)
if(!(f_exp ^ 0xff) && !!(f_frac)){
// f is NaN, return f
negate_fb = f;
} else{
// change sign of MSB and remove back on its position
int sign = ((f >> 31) ^ 0x1) << 31;
// reassamble msb and exp and frac part
negate_fb = sign | expr;
}
return negate_fb;
}
/*
function which computer the absolute value of a floating-point number
returns:
- |f|, if f is not NaN
- f, if f is NaN
*/
float_bits float_absval(float_bits f){
unsigned absval;
// check for NaN
int expr0 = (0xff << 8) | 0xff; //0xffff
int expr2 = (0x7f << 8) | 0xff; //0x7fff
//set MSB to 0
int mask1 = (expr2 << 16)| expr0; //0x7fffffff
int expr = f & mask1;
//get exp_part
int f_exp = expr >> 23;
int mask2 = (0x7f << 8) | 0xff;
mask2 = (mask2 << 8) | 0xff; //0x7fffff
int f_frac = f & mask2;
// check if f is NaN (first check exponent and then fractional part)
if(!(f_exp ^ 0xff) && !!(f_frac)){
// f is NaN
absval = f;
} else {
//set MSB to 0 and return back to its position
int sign = ((f >> 31) & 0x0) << 31;
absval = sign | expr;
}
return absval;
}
// /*
// * function which doubles a floating-point number;
// * Given a parameter f, this function will compute 2 ´ f.
// * If f is Nan, the function should simply return f.
// */
float_bits float_twice(float_bits f){
unsigned float_twice;
// check for NaN
int expr0 = (0xff << 8) | 0xff; //0xffff
int expr2 = (0x7f << 8) | 0xff; //0x7fff
//set MSB to 0
int mask1 = (expr2 << 16)| expr0; //0x7fffffff
int expr = f & mask1;
//get exp_part
int f_exp = expr >> 23;
int mask2 = (0x7f << 8) | 0xff;
mask2 = (mask2 << 8) | 0xff; //0x7fffff
int f_frac = f & mask2;
// check if f is NaN (first check exponent and then fractional part)
if(!(f_exp ^ 0xff) && !!(f_frac)){
// f is NaN
float_twice = f;
} else {
// when we double floating point number, fractional part stays the same, by the exponent changes
f_exp = f_exp + 1;
int sign = f & (0x80 << 24);
// reassamble sign, exponent and fractional parts of f
float_twice = sign | (f_exp << 23) | f_frac;
}
return float_twice;
}
//
// /*
// * function which halves a floating-point number;
// * Given a parameter f, this function will compute 0.5 ´ f.
// * If f is Nan, the function should simply return f.
// */
float_bits float_half(float_bits f){
unsigned float_half;
// check for NaN
int expr0 = (0xff << 8) | 0xff; //0xffff
int expr2 = (0x7f << 8) | 0xff; //0x7fff
//set MSB to 0
int mask1 = (expr2 << 16)| expr0; //0x7fffffff
int expr = f & mask1;
//get exp_part
int f_exp = expr >> 23;
int mask2 = (0x7f << 8) | 0xff;
mask2 = (mask2 << 8) | 0xff; //0x7fffff
int f_frac = f & mask2;
// check if f is NaN (first check exponent and then fractional part)
if(!(f_exp ^ 0xff) && !!(f_frac)){
// f is NaN
float_half = f;
} else {
// when we half floating point number,fractional part stays the same, but the exponent changes
f_exp = f_exp - 1;
int sign = f & (0x80 << 24);
// reassamble sign,exp and frac parts of f
float_half = sign | (f_exp << 23) | f_frac;
}
return float_half;
}
int main(){
/*
* params to test float_class(float_bits f)
*/
unsigned int x1 = 0x5555ffff;
//unsigned int x1 = 0x0000ffff;
//unsigned int x1 = 0xffffffff;
printf("float_class(x1) = %d\n",float_class(x1));
/*
* params to test float_negate(float_bits f)
*/
unsigned int x2 = 0x40000000;
printf("float_negate(x2) = %u\n",float_negate(x2));
/*
* params to test float_absval(float_bits f)
*/
unsigned int x3 = 0xc5001040;
printf("float_absval(x3) = %u\n",float_absval(x3));
/*
* params to test float_twice(float_bits f)
*/
unsigned int x4 = 0x44000000;
printf("float_twice(x4) = %u\n",float_twice(x4));
/*
* params to test float_half(float_bits f)
*/
unsigned int x5 = 0x43560000;
printf("float_half(x5) = %u\n",float_half(x5));
}