Subversion Repositories HelenOS-historic

Rev

Rev 876 | Rev 1035 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
647 cejka 1
/*
2
 * Copyright (C) 2005 Josef Cejka
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
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
15
 *   derived from this software without specific prior written permission.
16
 *
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
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
697 cejka 29
#include "sftypes.h"
30
#include "conversion.h"
857 cejka 31
#include "comparison.h"
874 cejka 32
#include "common.h"
697 cejka 33
 
34
float64 convertFloat32ToFloat64(float32 a)
35
{
36
    float64 result;
1031 cejka 37
    uint64_t frac;
697 cejka 38
 
39
    result.parts.sign = a.parts.sign;
804 cejka 40
    result.parts.fraction = a.parts.fraction;
41
    result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
697 cejka 42
 
43
    if ((isFloat32Infinity(a))||(isFloat32NaN(a))) {
44
        result.parts.exp = 0x7FF;
45
        /* TODO; check if its correct for SigNaNs*/
46
        return result;
47
    };
48
 
49
    result.parts.exp = a.parts.exp + ( (int)FLOAT64_BIAS - FLOAT32_BIAS );
50
    if (a.parts.exp == 0) {
51
        /* normalize denormalized numbers */
52
 
804 cejka 53
        if (result.parts.fraction == 0ll) { /* fix zero */
697 cejka 54
            result.parts.exp = 0ll;
55
            return result;
56
        }
57
 
804 cejka 58
        frac = result.parts.fraction;
697 cejka 59
 
804 cejka 60
        while (!(frac & (0x10000000000000ll))) {
61
            frac <<= 1;
697 cejka 62
            --result.parts.exp;
63
        };
698 cejka 64
 
65
        ++result.parts.exp;
804 cejka 66
        result.parts.fraction = frac;
697 cejka 67
    };
68
 
69
    return result;
70
 
857 cejka 71
}
697 cejka 72
 
73
float32 convertFloat64ToFloat32(float64 a)
74
{
75
    float32 result;
1031 cejka 76
    int32_t exp;
77
    uint64_t frac;
697 cejka 78
 
79
    result.parts.sign = a.parts.sign;
80
 
81
    if (isFloat64NaN(a)) {
82
 
83
        result.parts.exp = 0xFF;
84
 
85
        if (isFloat64SigNaN(a)) {
1031 cejka 86
            result.parts.fraction = 0x400000; /* set first bit of fraction nonzero */
697 cejka 87
            return result;
88
        }
89
 
804 cejka 90
        result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
697 cejka 91
        return result;
92
    };
93
 
94
    if (isFloat64Infinity(a)) {
804 cejka 95
        result.parts.fraction = 0;
697 cejka 96
        result.parts.exp = 0xFF;
97
        return result;
98
    };
99
 
100
    exp = (int)a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
101
 
102
    if (exp >= 0xFF) {
103
        /*FIXME: overflow*/
804 cejka 104
        result.parts.fraction = 0;
697 cejka 105
        result.parts.exp = 0xFF;
106
        return result;
107
 
108
    } else if (exp <= 0 ) {
109
 
110
        /* underflow or denormalized */
111
 
112
        result.parts.exp = 0;
113
 
114
        exp *= -1; 
804 cejka 115
        if (exp > FLOAT32_FRACTION_SIZE ) {
697 cejka 116
            /* FIXME: underflow */
804 cejka 117
            result.parts.fraction = 0;
697 cejka 118
            return result;
119
        };
120
 
121
        /* denormalized */
122
 
804 cejka 123
        frac = a.parts.fraction;
124
        frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
697 cejka 125
 
804 cejka 126
        frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
698 cejka 127
 
697 cejka 128
        while (exp > 0) {
129
            --exp;
804 cejka 130
            frac >>= 1;
697 cejka 131
        };
804 cejka 132
        result.parts.fraction = frac;
697 cejka 133
 
134
        return result;
135
    };
136
 
137
    result.parts.exp = exp;
804 cejka 138
    result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
697 cejka 139
    return result;
857 cejka 140
}
697 cejka 141
 
857 cejka 142
 
143
/** Helping procedure for converting float32 to uint32
144
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
145
 * @return unsigned integer
146
 */
1031 cejka 147
static uint32_t _float32_to_uint32_helper(float32 a)
857 cejka 148
{
1031 cejka 149
    uint32_t frac;
857 cejka 150
 
151
    if (a.parts.exp < FLOAT32_BIAS) {
152
        /*TODO: rounding*/
153
        return 0;
154
    }
155
 
156
    frac = a.parts.fraction;
157
 
158
    frac |= FLOAT32_HIDDEN_BIT_MASK;
159
    /* shift fraction to left so hidden bit will be the most significant bit */
160
    frac <<= 32 - FLOAT32_FRACTION_SIZE - 1;
161
 
162
    frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
163
    if ((a.parts.sign == 1) && (frac != 0)) {
164
        frac = ~frac;
165
        ++frac;
166
    }
167
 
168
    return frac;
169
}
170
 
171
/* Convert float to unsigned int32
172
 * FIXME: Im not sure what to return if overflow/underflow happens
173
 *  - now its the biggest or the smallest int
174
 */
1031 cejka 175
uint32_t float32_to_uint32(float32 a)
857 cejka 176
{
177
    if (isFloat32NaN(a)) {
178
        return MAX_UINT32;
179
    }
180
 
181
    if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
182
        if (a.parts.sign) {
183
            return MIN_UINT32;
184
        }
185
        return MAX_UINT32;
186
    }
187
 
188
    return _float32_to_uint32_helper(a);   
189
}
190
 
191
/* Convert float to signed int32
192
 * FIXME: Im not sure what to return if overflow/underflow happens
193
 *  - now its the biggest or the smallest int
194
 */
1031 cejka 195
int32_t float32_to_int32(float32 a)
857 cejka 196
{
197
    if (isFloat32NaN(a)) {
198
        return MAX_INT32;
199
    }
200
 
201
    if (isFloat32Infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS)))  {
202
        if (a.parts.sign) {
203
            return MIN_INT32;
204
        }
205
        return MAX_INT32;
206
    }
207
    return _float32_to_uint32_helper(a);
208
}  
209
 
210
 
865 cejka 211
/** Helping procedure for converting float64 to uint64
212
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
213
 * @return unsigned integer
214
 */
1031 cejka 215
static uint64_t _float64_to_uint64_helper(float64 a)
865 cejka 216
{
1031 cejka 217
    uint64_t frac;
865 cejka 218
 
219
    if (a.parts.exp < FLOAT64_BIAS) {
220
        /*TODO: rounding*/
221
        return 0;
222
    }
223
 
224
    frac = a.parts.fraction;
225
 
226
    frac |= FLOAT64_HIDDEN_BIT_MASK;
227
    /* shift fraction to left so hidden bit will be the most significant bit */
228
    frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
857 cejka 229
 
865 cejka 230
    frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
231
    if ((a.parts.sign == 1) && (frac != 0)) {
232
        frac = ~frac;
233
        ++frac;
234
    }
235
 
236
    return frac;
237
}
238
 
239
/* Convert float to unsigned int64
240
 * FIXME: Im not sure what to return if overflow/underflow happens
241
 *  - now its the biggest or the smallest int
242
 */
1031 cejka 243
uint64_t float64_to_uint64(float64 a)
865 cejka 244
{
245
    if (isFloat64NaN(a)) {
246
        return MAX_UINT64;
247
    }
248
 
249
    if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
250
        if (a.parts.sign) {
251
            return MIN_UINT64;
252
        }
253
        return MAX_UINT64;
254
    }
255
 
256
    return _float64_to_uint64_helper(a);   
257
}
258
 
259
/* Convert float to signed int64
260
 * FIXME: Im not sure what to return if overflow/underflow happens
261
 *  - now its the biggest or the smallest int
262
 */
1031 cejka 263
int64_t float64_to_int64(float64 a)
865 cejka 264
{
265
    if (isFloat64NaN(a)) {
266
        return MAX_INT64;
267
    }
268
 
269
    if (isFloat64Infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS)))  {
270
        if (a.parts.sign) {
271
            return MIN_INT64;
272
        }
273
        return MAX_INT64;
274
    }
275
    return _float64_to_uint64_helper(a);
276
}  
277
 
278
 
279
 
280
 
281
 
282
/** Helping procedure for converting float32 to uint64
283
 * @param a floating point number in normalized form (no NaNs or Inf are checked )
284
 * @return unsigned integer
285
 */
1031 cejka 286
static uint64_t _float32_to_uint64_helper(float32 a)
865 cejka 287
{
1031 cejka 288
    uint64_t frac;
865 cejka 289
 
290
    if (a.parts.exp < FLOAT32_BIAS) {
291
        /*TODO: rounding*/
292
        return 0;
293
    }
294
 
295
    frac = a.parts.fraction;
296
 
297
    frac |= FLOAT32_HIDDEN_BIT_MASK;
298
    /* shift fraction to left so hidden bit will be the most significant bit */
299
    frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
300
 
301
    frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
302
    if ((a.parts.sign == 1) && (frac != 0)) {
303
        frac = ~frac;
304
        ++frac;
305
    }
306
 
307
    return frac;
308
}
309
 
310
/* Convert float to unsigned int64
311
 * FIXME: Im not sure what to return if overflow/underflow happens
312
 *  - now its the biggest or the smallest int
313
 */
1031 cejka 314
uint64_t float32_to_uint64(float32 a)
865 cejka 315
{
316
    if (isFloat32NaN(a)) {
317
        return MAX_UINT64;
318
    }
319
 
320
    if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
321
        if (a.parts.sign) {
322
            return MIN_UINT64;
323
        }
324
        return MAX_UINT64;
325
    }
326
 
327
    return _float32_to_uint64_helper(a);   
328
}
329
 
330
/* Convert float to signed int64
331
 * FIXME: Im not sure what to return if overflow/underflow happens
332
 *  - now its the biggest or the smallest int
333
 */
1031 cejka 334
int64_t float32_to_int64(float32 a)
865 cejka 335
{
336
    if (isFloat32NaN(a)) {
337
        return MAX_INT64;
338
    }
339
 
340
    if (isFloat32Infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS)))  {
341
        if (a.parts.sign) {
342
            return (MIN_INT64);
343
        }
344
        return MAX_INT64;
345
    }
346
    return _float32_to_uint64_helper(a);
347
}  
348
 
349
 
350
/* Convert float64 to unsigned int32
351
 * FIXME: Im not sure what to return if overflow/underflow happens
352
 *  - now its the biggest or the smallest int
353
 */
1031 cejka 354
uint32_t float64_to_uint32(float64 a)
865 cejka 355
{
356
    if (isFloat64NaN(a)) {
357
        return MAX_UINT32;
358
    }
359
 
360
    if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
361
        if (a.parts.sign) {
362
            return MIN_UINT32;
363
        }
364
        return MAX_UINT32;
365
    }
366
 
1031 cejka 367
    return (uint32_t)_float64_to_uint64_helper(a); 
865 cejka 368
}
369
 
370
/* Convert float64 to signed int32
371
 * FIXME: Im not sure what to return if overflow/underflow happens
372
 *  - now its the biggest or the smallest int
373
 */
1031 cejka 374
int32_t float64_to_int32(float64 a)
865 cejka 375
{
376
    if (isFloat64NaN(a)) {
377
        return MAX_INT32;
378
    }
379
 
380
    if (isFloat64Infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS)))  {
381
        if (a.parts.sign) {
382
            return MIN_INT32;
383
        }
384
        return MAX_INT32;
385
    }
1031 cejka 386
    return (int32_t)_float64_to_uint64_helper(a);
865 cejka 387
}  
388
 
874 cejka 389
/** Convert unsigned integer to float32
390
 *
391
 *
392
 */
1031 cejka 393
float32 uint32_to_float32(uint32_t i)
874 cejka 394
{
395
    int counter;
1031 cejka 396
    int32_t exp;
874 cejka 397
    float32 result;
398
 
399
    result.parts.sign = 0;
400
    result.parts.fraction = 0;
865 cejka 401
 
874 cejka 402
    counter = countZeroes32(i);
403
 
404
    exp = FLOAT32_BIAS + 32 - counter - 1;
405
 
406
    if (counter == 32) {
407
        result.binary = 0;
408
        return result;
409
    }
410
 
411
    if (counter > 0) {
412
        i <<= counter - 1;
413
    } else {
414
        i >>= 1;
415
    }
416
 
417
    roundFloat32(&exp, &i);
418
 
419
    result.parts.fraction = i >> 7;
420
    result.parts.exp = exp;
421
 
422
    return result;
423
}
424
 
1031 cejka 425
float32 int32_to_float32(int32_t i)
874 cejka 426
{
427
    float32 result;
428
 
429
    if (i < 0) {
1031 cejka 430
        result = uint32_to_float32((uint32_t)(-i));
874 cejka 431
    } else {
1031 cejka 432
        result = uint32_to_float32((uint32_t)i);
874 cejka 433
    }
434
 
435
    result.parts.sign = i < 0;
436
 
437
    return result;
438
}
439
 
440
 
1031 cejka 441
float32 uint64_to_float32(uint64_t i)
874 cejka 442
{
875 cejka 443
    int counter;
1031 cejka 444
    int32_t exp;
445
    int32_t j;
875 cejka 446
    float32 result;
447
 
448
    result.parts.sign = 0;
449
    result.parts.fraction = 0;
450
 
451
    counter = countZeroes64(i);
452
 
453
    exp = FLOAT32_BIAS + 64 - counter - 1;
454
 
455
    if (counter == 64) {
456
        result.binary = 0;
457
        return result;
458
    }
459
 
460
    /* Shift all to the first 31 bits (31. will be hidden 1)*/
461
    if (counter > 33) {
462
        i <<= counter - 1 - 32;
463
    } else {
464
        i >>= 1 + 32 - counter;
465
    }
1031 cejka 466
 
467
    j = (uint32_t)i;
468
    roundFloat32(&exp, &j);
875 cejka 469
 
1031 cejka 470
    result.parts.fraction = j >> 7;
875 cejka 471
    result.parts.exp = exp;
472
    return result;
874 cejka 473
}
474
 
1031 cejka 475
float32 int64_to_float32(int64_t i)
874 cejka 476
{
477
    float32 result;
478
 
479
    if (i < 0) {
1031 cejka 480
        result = uint64_to_float32((uint64_t)(-i));
874 cejka 481
    } else {
1031 cejka 482
        result = uint64_to_float32((uint64_t)i);
874 cejka 483
    }
484
 
485
    result.parts.sign = i < 0;
486
 
487
    return result;
488
}
876 cejka 489
 
490
/** Convert unsigned integer to float64
491
 *
492
 *
493
 */
1031 cejka 494
float64 uint32_to_float64(uint32_t i)
876 cejka 495
{
496
    int counter;
1031 cejka 497
    int32_t exp;
876 cejka 498
    float64 result;
1031 cejka 499
    uint64_t frac;
876 cejka 500
 
501
    result.parts.sign = 0;
502
    result.parts.fraction = 0;
503
 
504
    counter = countZeroes32(i);
505
 
506
    exp = FLOAT64_BIAS + 32 - counter - 1;
507
 
508
    if (counter == 32) {
509
        result.binary = 0;
510
        return result;
511
    }
512
 
513
    frac = i;
514
    frac <<= counter + 32 - 1;
515
 
516
    roundFloat64(&exp, &frac);
517
 
518
    result.parts.fraction = frac >> 10;
519
    result.parts.exp = exp;
520
 
521
    return result;
522
}
523
 
1031 cejka 524
float64 int32_to_float64(int32_t i)
876 cejka 525
{
526
    float64 result;
527
 
528
    if (i < 0) {
1031 cejka 529
        result = uint32_to_float64((uint32_t)(-i));
876 cejka 530
    } else {
1031 cejka 531
        result = uint32_to_float64((uint32_t)i);
876 cejka 532
    }
533
 
534
    result.parts.sign = i < 0;
535
 
536
    return result;
537
}
538
 
539
 
1031 cejka 540
float64 uint64_to_float64(uint64_t i)
876 cejka 541
{
542
    int counter;
1031 cejka 543
    int32_t exp;
876 cejka 544
    float64 result;
545
 
546
    result.parts.sign = 0;
547
    result.parts.fraction = 0;
548
 
549
    counter = countZeroes64(i);
550
 
551
    exp = FLOAT64_BIAS + 64 - counter - 1;
552
 
553
    if (counter == 64) {
554
        result.binary = 0;
555
        return result;
556
    }
557
 
558
    if (counter > 0) {
559
        i <<= counter - 1;
560
    } else {
561
        i >>= 1;
562
    }
563
 
564
    roundFloat64(&exp, &i);
565
 
566
    result.parts.fraction = i >> 10;
567
    result.parts.exp = exp;
568
    return result;
569
}
570
 
1031 cejka 571
float64 int64_to_float64(int64_t i)
876 cejka 572
{
573
    float64 result;
574
 
575
    if (i < 0) {
1031 cejka 576
        result = uint64_to_float64((uint64_t)(-i));
876 cejka 577
    } else {
1031 cejka 578
        result = uint64_to_float64((uint64_t)i);
876 cejka 579
    }
580
 
581
    result.parts.sign = i < 0;
582
 
583
    return result;
584
}
585
 
586