Subversion Repositories HelenOS-historic

Rev

Rev 857 | Rev 874 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 857 Rev 865
1
/*
1
/*
2
 * Copyright (C) 2005 Josef Cejka
2
 * Copyright (C) 2005 Josef Cejka
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
#include "sftypes.h"
29
#include "sftypes.h"
30
#include "conversion.h"
30
#include "conversion.h"
31
#include "comparison.h"
31
#include "comparison.h"
32
 
32
 
33
float64 convertFloat32ToFloat64(float32 a)
33
float64 convertFloat32ToFloat64(float32 a)
34
{
34
{
35
    float64 result;
35
    float64 result;
36
    __u64 frac;
36
    __u64 frac;
37
   
37
   
38
    result.parts.sign = a.parts.sign;
38
    result.parts.sign = a.parts.sign;
39
    result.parts.fraction = a.parts.fraction;
39
    result.parts.fraction = a.parts.fraction;
40
    result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
40
    result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
41
   
41
   
42
    if ((isFloat32Infinity(a))||(isFloat32NaN(a))) {
42
    if ((isFloat32Infinity(a))||(isFloat32NaN(a))) {
43
        result.parts.exp = 0x7FF;
43
        result.parts.exp = 0x7FF;
44
        /* TODO; check if its correct for SigNaNs*/
44
        /* TODO; check if its correct for SigNaNs*/
45
        return result;
45
        return result;
46
    };
46
    };
47
   
47
   
48
    result.parts.exp = a.parts.exp + ( (int)FLOAT64_BIAS - FLOAT32_BIAS );
48
    result.parts.exp = a.parts.exp + ( (int)FLOAT64_BIAS - FLOAT32_BIAS );
49
    if (a.parts.exp == 0) {
49
    if (a.parts.exp == 0) {
50
        /* normalize denormalized numbers */
50
        /* normalize denormalized numbers */
51
 
51
 
52
        if (result.parts.fraction == 0ll) { /* fix zero */
52
        if (result.parts.fraction == 0ll) { /* fix zero */
53
            result.parts.exp = 0ll;
53
            result.parts.exp = 0ll;
54
            return result;
54
            return result;
55
        }
55
        }
56
           
56
           
57
        frac = result.parts.fraction;
57
        frac = result.parts.fraction;
58
       
58
       
59
        while (!(frac & (0x10000000000000ll))) {
59
        while (!(frac & (0x10000000000000ll))) {
60
            frac <<= 1;
60
            frac <<= 1;
61
            --result.parts.exp;
61
            --result.parts.exp;
62
        };
62
        };
63
       
63
       
64
        ++result.parts.exp;
64
        ++result.parts.exp;
65
        result.parts.fraction = frac;
65
        result.parts.fraction = frac;
66
    };
66
    };
67
   
67
   
68
    return result;
68
    return result;
69
   
69
   
70
}
70
}
71
 
71
 
72
float32 convertFloat64ToFloat32(float64 a)
72
float32 convertFloat64ToFloat32(float64 a)
73
{
73
{
74
    float32 result;
74
    float32 result;
75
    __s32 exp;
75
    __s32 exp;
76
    __u64 frac;
76
    __u64 frac;
77
   
77
   
78
    result.parts.sign = a.parts.sign;
78
    result.parts.sign = a.parts.sign;
79
   
79
   
80
    if (isFloat64NaN(a)) {
80
    if (isFloat64NaN(a)) {
81
       
81
       
82
        result.parts.exp = 0xFF;
82
        result.parts.exp = 0xFF;
83
       
83
       
84
        if (isFloat64SigNaN(a)) {
84
        if (isFloat64SigNaN(a)) {
85
            result.parts.fraction = 0x800000; /* set first bit of fraction nonzero */
85
            result.parts.fraction = 0x800000; /* set first bit of fraction nonzero */
86
            return result;
86
            return result;
87
        }
87
        }
88
   
88
   
89
        result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
89
        result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
90
        return result;
90
        return result;
91
    };
91
    };
92
 
92
 
93
    if (isFloat64Infinity(a)) {
93
    if (isFloat64Infinity(a)) {
94
        result.parts.fraction = 0;
94
        result.parts.fraction = 0;
95
        result.parts.exp = 0xFF;
95
        result.parts.exp = 0xFF;
96
        return result;
96
        return result;
97
    };
97
    };
98
 
98
 
99
    exp = (int)a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
99
    exp = (int)a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
100
   
100
   
101
    if (exp >= 0xFF) {
101
    if (exp >= 0xFF) {
102
        /*FIXME: overflow*/
102
        /*FIXME: overflow*/
103
        result.parts.fraction = 0;
103
        result.parts.fraction = 0;
104
        result.parts.exp = 0xFF;
104
        result.parts.exp = 0xFF;
105
        return result;
105
        return result;
106
       
106
       
107
    } else if (exp <= 0 ) {
107
    } else if (exp <= 0 ) {
108
       
108
       
109
        /* underflow or denormalized */
109
        /* underflow or denormalized */
110
       
110
       
111
        result.parts.exp = 0;
111
        result.parts.exp = 0;
112
       
112
       
113
        exp *= -1; 
113
        exp *= -1; 
114
        if (exp > FLOAT32_FRACTION_SIZE ) {
114
        if (exp > FLOAT32_FRACTION_SIZE ) {
115
            /* FIXME: underflow */
115
            /* FIXME: underflow */
116
            result.parts.fraction = 0;
116
            result.parts.fraction = 0;
117
            return result;
117
            return result;
118
        };
118
        };
119
       
119
       
120
        /* denormalized */
120
        /* denormalized */
121
       
121
       
122
        frac = a.parts.fraction;
122
        frac = a.parts.fraction;
123
        frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
123
        frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
124
       
124
       
125
        frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
125
        frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
126
       
126
       
127
        while (exp > 0) {
127
        while (exp > 0) {
128
            --exp;
128
            --exp;
129
            frac >>= 1;
129
            frac >>= 1;
130
        };
130
        };
131
        result.parts.fraction = frac;
131
        result.parts.fraction = frac;
132
       
132
       
133
        return result;
133
        return result;
134
    };
134
    };
135
 
135
 
136
    result.parts.exp = exp;
136
    result.parts.exp = exp;
137
    result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
137
    result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
138
    return result;
138
    return result;
139
}
139
}
140
 
140
 
141
 
141
 
142
/** Helping procedure for converting float32 to uint32
142
/** Helping procedure for converting float32 to uint32
143
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
143
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
144
 * @return unsigned integer
144
 * @return unsigned integer
145
 */
145
 */
146
static __u32 _float32_to_uint32_helper(float32 a)
146
static __u32 _float32_to_uint32_helper(float32 a)
147
{
147
{
148
    __u32 frac;
148
    __u32 frac;
149
   
149
   
150
    if (a.parts.exp < FLOAT32_BIAS) {
150
    if (a.parts.exp < FLOAT32_BIAS) {
151
        /*TODO: rounding*/
151
        /*TODO: rounding*/
152
        return 0;
152
        return 0;
153
    }
153
    }
154
   
154
   
155
    frac = a.parts.fraction;
155
    frac = a.parts.fraction;
156
   
156
   
157
    frac |= FLOAT32_HIDDEN_BIT_MASK;
157
    frac |= FLOAT32_HIDDEN_BIT_MASK;
158
    /* shift fraction to left so hidden bit will be the most significant bit */
158
    /* shift fraction to left so hidden bit will be the most significant bit */
159
    frac <<= 32 - FLOAT32_FRACTION_SIZE - 1;
159
    frac <<= 32 - FLOAT32_FRACTION_SIZE - 1;
160
 
160
 
161
    frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
161
    frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
162
    if ((a.parts.sign == 1) && (frac != 0)) {
162
    if ((a.parts.sign == 1) && (frac != 0)) {
163
        frac = ~frac;
163
        frac = ~frac;
164
        ++frac;
164
        ++frac;
165
    }
165
    }
166
   
166
   
167
    return frac;
167
    return frac;
168
}
168
}
169
 
169
 
170
/* Convert float to unsigned int32
170
/* Convert float to unsigned int32
171
 * FIXME: Im not sure what to return if overflow/underflow happens
171
 * FIXME: Im not sure what to return if overflow/underflow happens
172
 *  - now its the biggest or the smallest int
172
 *  - now its the biggest or the smallest int
173
 */
173
 */
174
__u32 float32_to_uint32(float32 a)
174
__u32 float32_to_uint32(float32 a)
175
{
175
{
176
    if (isFloat32NaN(a)) {
176
    if (isFloat32NaN(a)) {
177
        return MAX_UINT32;
177
        return MAX_UINT32;
178
    }
178
    }
179
   
179
   
180
    if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
180
    if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
181
        if (a.parts.sign) {
181
        if (a.parts.sign) {
182
            return MIN_UINT32;
182
            return MIN_UINT32;
183
        }
183
        }
184
        return MAX_UINT32;
184
        return MAX_UINT32;
185
    }
185
    }
186
   
186
   
187
    return _float32_to_uint32_helper(a);   
187
    return _float32_to_uint32_helper(a);   
188
}
188
}
189
 
189
 
190
/* Convert float to signed int32
190
/* Convert float to signed int32
191
 * FIXME: Im not sure what to return if overflow/underflow happens
191
 * FIXME: Im not sure what to return if overflow/underflow happens
192
 *  - now its the biggest or the smallest int
192
 *  - now its the biggest or the smallest int
193
 */
193
 */
194
__s32 float32_to_int32(float32 a)
194
__s32 float32_to_int32(float32 a)
195
{
195
{
196
    if (isFloat32NaN(a)) {
196
    if (isFloat32NaN(a)) {
197
        return MAX_INT32;
197
        return MAX_INT32;
198
    }
198
    }
199
   
199
   
200
    if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
200
    if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
201
        if (a.parts.sign) {
201
        if (a.parts.sign) {
202
            return MIN_INT32;
202
            return MIN_INT32;
203
        }
203
        }
204
        return MAX_INT32;
204
        return MAX_INT32;
205
    }
205
    }
206
    return _float32_to_uint32_helper(a);
206
    return _float32_to_uint32_helper(a);
207
}  
207
}  
208
 
208
 
209
 
209
 
-
 
210
/** Helping procedure for converting float64 to uint64
-
 
211
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
-
 
212
 * @return unsigned integer
-
 
213
 */
-
 
214
static __u64 _float64_to_uint64_helper(float64 a)
-
 
215
{
-
 
216
    __u64 frac;
-
 
217
   
-
 
218
    if (a.parts.exp < FLOAT64_BIAS) {
-
 
219
        /*TODO: rounding*/
-
 
220
        return 0;
-
 
221
    }
-
 
222
   
-
 
223
    frac = a.parts.fraction;
-
 
224
   
-
 
225
    frac |= FLOAT64_HIDDEN_BIT_MASK;
-
 
226
    /* shift fraction to left so hidden bit will be the most significant bit */
-
 
227
    frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
-
 
228
 
-
 
229
    frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
-
 
230
    if ((a.parts.sign == 1) && (frac != 0)) {
-
 
231
        frac = ~frac;
-
 
232
        ++frac;
-
 
233
    }
-
 
234
   
-
 
235
    return frac;
-
 
236
}
-
 
237
 
-
 
238
/* Convert float to unsigned int64
-
 
239
 * FIXME: Im not sure what to return if overflow/underflow happens
-
 
240
 *  - now its the biggest or the smallest int
-
 
241
 */
-
 
242
__u64 float64_to_uint64(float64 a)
-
 
243
{
-
 
244
    if (isFloat64NaN(a)) {
-
 
245
        return MAX_UINT64;
-
 
246
    }
-
 
247
   
-
 
248
    if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
-
 
249
        if (a.parts.sign) {
-
 
250
            return MIN_UINT64;
-
 
251
        }
-
 
252
        return MAX_UINT64;
-
 
253
    }
-
 
254
   
-
 
255
    return _float64_to_uint64_helper(a);   
-
 
256
}
-
 
257
 
-
 
258
/* Convert float to signed int64
-
 
259
 * FIXME: Im not sure what to return if overflow/underflow happens
-
 
260
 *  - now its the biggest or the smallest int
-
 
261
 */
-
 
262
__s64 float64_to_int64(float64 a)
-
 
263
{
-
 
264
    if (isFloat64NaN(a)) {
-
 
265
        return MAX_INT64;
-
 
266
    }
-
 
267
   
-
 
268
    if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
-
 
269
        if (a.parts.sign) {
-
 
270
            return MIN_INT64;
-
 
271
        }
-
 
272
        return MAX_INT64;
-
 
273
    }
-
 
274
    return _float64_to_uint64_helper(a);
-
 
275
}  
-
 
276
 
-
 
277
 
-
 
278
 
-
 
279
 
-
 
280
 
-
 
281
/** Helping procedure for converting float32 to uint64
-
 
282
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
-
 
283
 * @return unsigned integer
-
 
284
 */
-
 
285
static __u64 _float32_to_uint64_helper(float32 a)
-
 
286
{
-
 
287
    __u64 frac;
-
 
288
   
-
 
289
    if (a.parts.exp < FLOAT32_BIAS) {
-
 
290
        /*TODO: rounding*/
-
 
291
        return 0;
-
 
292
    }
-
 
293
   
-
 
294
    frac = a.parts.fraction;
-
 
295
   
-
 
296
    frac |= FLOAT32_HIDDEN_BIT_MASK;
-
 
297
    /* shift fraction to left so hidden bit will be the most significant bit */
-
 
298
    frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
-
 
299
 
-
 
300
    frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
-
 
301
    if ((a.parts.sign == 1) && (frac != 0)) {
-
 
302
        frac = ~frac;
-
 
303
        ++frac;
-
 
304
    }
-
 
305
   
-
 
306
    return frac;
-
 
307
}
-
 
308
 
-
 
309
/* Convert float to unsigned int64
-
 
310
 * FIXME: Im not sure what to return if overflow/underflow happens
-
 
311
 *  - now its the biggest or the smallest int
-
 
312
 */
-
 
313
__u64 float32_to_uint64(float32 a)
-
 
314
{
-
 
315
    if (isFloat32NaN(a)) {
-
 
316
        return MAX_UINT64;
-
 
317
    }
-
 
318
   
-
 
319
    if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
-
 
320
        if (a.parts.sign) {
-
 
321
            return MIN_UINT64;
-
 
322
        }
-
 
323
        return MAX_UINT64;
-
 
324
    }
-
 
325
   
-
 
326
    return _float32_to_uint64_helper(a);   
-
 
327
}
-
 
328
 
-
 
329
/* Convert float to signed int64
-
 
330
 * FIXME: Im not sure what to return if overflow/underflow happens
-
 
331
 *  - now its the biggest or the smallest int
-
 
332
 */
-
 
333
__s64 float32_to_int64(float32 a)
-
 
334
{
-
 
335
    if (isFloat32NaN(a)) {
-
 
336
        return MAX_INT64;
-
 
337
    }
-
 
338
   
-
 
339
    if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
-
 
340
        if (a.parts.sign) {
-
 
341
            return (MIN_INT64);
-
 
342
        }
-
 
343
        return MAX_INT64;
-
 
344
    }
-
 
345
    return _float32_to_uint64_helper(a);
-
 
346
}  
-
 
347
 
-
 
348
 
-
 
349
/* Convert float64 to unsigned int32
-
 
350
 * FIXME: Im not sure what to return if overflow/underflow happens
-
 
351
 *  - now its the biggest or the smallest int
-
 
352
 */
-
 
353
__u32 float64_to_uint32(float64 a)
-
 
354
{
-
 
355
    if (isFloat64NaN(a)) {
-
 
356
        return MAX_UINT32;
-
 
357
    }
-
 
358
   
-
 
359
    if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
-
 
360
        if (a.parts.sign) {
-
 
361
            return MIN_UINT32;
-
 
362
        }
-
 
363
        return MAX_UINT32;
-
 
364
    }
-
 
365
   
-
 
366
    return (__u32)_float64_to_uint64_helper(a);
-
 
367
}
-
 
368
 
-
 
369
/* Convert float64 to signed int32
-
 
370
 * FIXME: Im not sure what to return if overflow/underflow happens
-
 
371
 *  - now its the biggest or the smallest int
-
 
372
 */
-
 
373
__s32 float64_to_int32(float64 a)
-
 
374
{
-
 
375
    if (isFloat64NaN(a)) {
-
 
376
        return MAX_INT32;
-
 
377
    }
-
 
378
   
-
 
379
    if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
-
 
380
        if (a.parts.sign) {
-
 
381
            return MIN_INT32;
-
 
382
        }
-
 
383
        return MAX_INT32;
-
 
384
    }
-
 
385
    return (__s32)_float64_to_uint64_helper(a);
-
 
386
}  
-
 
387
 
210
 
388
 
211
 
389