source: mainline/uspace/lib/softfloat/generic/conversion.c@ 8b1e15ac

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8b1e15ac was 9539be6, checked in by Martin Decky <martin@…>, 15 years ago

autotool now also detects values of UINT_MAX and friends

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