source: mainline/uspace/lib/softfloat/generic/conversion.c@ 41455a22

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 41455a22 was 88d5c1e, checked in by Martin Decky <martin@…>, 13 years ago

softfloat redesign

  • avoid hardwired type sizes, actual sizes are determined at compile-time
  • add basic support for x87 extended-precision data types (stored as 96bit long double)
  • a lot of coding style changes (removal of CamelCase, etc.)
  • Property mode set to 100644
File size: 21.9 KB
Line 
1/*
2 * Copyright (c) 2005 Josef Cejka
3 * Copyright (c) 2011 Petr Koupy
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup softfloat
31 * @{
32 */
33/** @file Conversion of precision and conversion between integers and floats.
34 */
35
36#include <sftypes.h>
37#include <conversion.h>
38#include <comparison.h>
39#include <common.h>
40
41float64 float32_to_float64(float32 a)
42{
43 float64 result;
44 uint64_t frac;
45
46 result.parts.sign = a.parts.sign;
47 result.parts.fraction = a.parts.fraction;
48 result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
49
50 if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
51 result.parts.exp = FLOAT64_MAX_EXPONENT;
52 // TODO; check if its correct for SigNaNs
53 return result;
54 }
55
56 result.parts.exp = a.parts.exp + ((int) FLOAT64_BIAS - FLOAT32_BIAS);
57 if (a.parts.exp == 0) {
58 /* normalize denormalized numbers */
59
60 if (result.parts.fraction == 0) { /* fix zero */
61 result.parts.exp = 0;
62 return result;
63 }
64
65 frac = result.parts.fraction;
66
67 while (!(frac & FLOAT64_HIDDEN_BIT_MASK)) {
68 frac <<= 1;
69 --result.parts.exp;
70 }
71
72 ++result.parts.exp;
73 result.parts.fraction = frac;
74 }
75
76 return result;
77}
78
79float128 float32_to_float128(float32 a)
80{
81 float128 result;
82 uint64_t frac_hi, frac_lo;
83 uint64_t tmp_hi, tmp_lo;
84
85 result.parts.sign = a.parts.sign;
86 result.parts.frac_hi = 0;
87 result.parts.frac_lo = a.parts.fraction;
88 lshift128(result.parts.frac_hi, result.parts.frac_lo,
89 (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE),
90 &frac_hi, &frac_lo);
91 result.parts.frac_hi = frac_hi;
92 result.parts.frac_lo = frac_lo;
93
94 if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
95 result.parts.exp = FLOAT128_MAX_EXPONENT;
96 // TODO; check if its correct for SigNaNs
97 return result;
98 }
99
100 result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT32_BIAS);
101 if (a.parts.exp == 0) {
102 /* normalize denormalized numbers */
103
104 if (eq128(result.parts.frac_hi,
105 result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
106 result.parts.exp = 0;
107 return result;
108 }
109
110 frac_hi = result.parts.frac_hi;
111 frac_lo = result.parts.frac_lo;
112
113 and128(frac_hi, frac_lo,
114 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
115 &tmp_hi, &tmp_lo);
116 while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
117 lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
118 --result.parts.exp;
119 }
120
121 ++result.parts.exp;
122 result.parts.frac_hi = frac_hi;
123 result.parts.frac_lo = frac_lo;
124 }
125
126 return result;
127}
128
129float128 float64_to_float128(float64 a)
130{
131 float128 result;
132 uint64_t frac_hi, frac_lo;
133 uint64_t tmp_hi, tmp_lo;
134
135 result.parts.sign = a.parts.sign;
136 result.parts.frac_hi = 0;
137 result.parts.frac_lo = a.parts.fraction;
138 lshift128(result.parts.frac_hi, result.parts.frac_lo,
139 (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE),
140 &frac_hi, &frac_lo);
141 result.parts.frac_hi = frac_hi;
142 result.parts.frac_lo = frac_lo;
143
144 if ((is_float64_infinity(a)) || (is_float64_nan(a))) {
145 result.parts.exp = FLOAT128_MAX_EXPONENT;
146 // TODO; check if its correct for SigNaNs
147 return result;
148 }
149
150 result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT64_BIAS);
151 if (a.parts.exp == 0) {
152 /* normalize denormalized numbers */
153
154 if (eq128(result.parts.frac_hi,
155 result.parts.frac_lo, 0x0ll, 0x0ll)) { /* fix zero */
156 result.parts.exp = 0;
157 return result;
158 }
159
160 frac_hi = result.parts.frac_hi;
161 frac_lo = result.parts.frac_lo;
162
163 and128(frac_hi, frac_lo,
164 FLOAT128_HIDDEN_BIT_MASK_HI, FLOAT128_HIDDEN_BIT_MASK_LO,
165 &tmp_hi, &tmp_lo);
166 while (!lt128(0x0ll, 0x0ll, tmp_hi, tmp_lo)) {
167 lshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
168 --result.parts.exp;
169 }
170
171 ++result.parts.exp;
172 result.parts.frac_hi = frac_hi;
173 result.parts.frac_lo = frac_lo;
174 }
175
176 return result;
177}
178
179float32 float64_to_float32(float64 a)
180{
181 float32 result;
182 int32_t exp;
183 uint64_t frac;
184
185 result.parts.sign = a.parts.sign;
186
187 if (is_float64_nan(a)) {
188 result.parts.exp = FLOAT32_MAX_EXPONENT;
189
190 if (is_float64_signan(a)) {
191 /* set first bit of fraction nonzero */
192 result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
193 return result;
194 }
195
196 /* fraction nonzero but its first bit is zero */
197 result.parts.fraction = 0x1;
198 return result;
199 }
200
201 if (is_float64_infinity(a)) {
202 result.parts.fraction = 0;
203 result.parts.exp = FLOAT32_MAX_EXPONENT;
204 return result;
205 }
206
207 exp = (int) a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
208
209 if (exp >= FLOAT32_MAX_EXPONENT) {
210 /* FIXME: overflow */
211 result.parts.fraction = 0;
212 result.parts.exp = FLOAT32_MAX_EXPONENT;
213 return result;
214 } else if (exp <= 0) {
215 /* underflow or denormalized */
216
217 result.parts.exp = 0;
218
219 exp *= -1;
220 if (exp > FLOAT32_FRACTION_SIZE) {
221 /* FIXME: underflow */
222 result.parts.fraction = 0;
223 return result;
224 }
225
226 /* denormalized */
227
228 frac = a.parts.fraction;
229 frac |= FLOAT64_HIDDEN_BIT_MASK; /* denormalize and set hidden bit */
230
231 frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
232
233 while (exp > 0) {
234 --exp;
235 frac >>= 1;
236 }
237 result.parts.fraction = frac;
238
239 return result;
240 }
241
242 result.parts.exp = exp;
243 result.parts.fraction =
244 a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
245 return result;
246}
247
248float32 float128_to_float32(float128 a)
249{
250 float32 result;
251 int32_t exp;
252 uint64_t frac_hi, frac_lo;
253
254 result.parts.sign = a.parts.sign;
255
256 if (is_float128_nan(a)) {
257 result.parts.exp = FLOAT32_MAX_EXPONENT;
258
259 if (is_float128_signan(a)) {
260 /* set first bit of fraction nonzero */
261 result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
262 return result;
263 }
264
265 /* fraction nonzero but its first bit is zero */
266 result.parts.fraction = 0x1;
267 return result;
268 }
269
270 if (is_float128_infinity(a)) {
271 result.parts.fraction = 0;
272 result.parts.exp = FLOAT32_MAX_EXPONENT;
273 return result;
274 }
275
276 exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT32_BIAS;
277
278 if (exp >= FLOAT32_MAX_EXPONENT) {
279 /* FIXME: overflow */
280 result.parts.fraction = 0;
281 result.parts.exp = FLOAT32_MAX_EXPONENT;
282 return result;
283 } else if (exp <= 0) {
284 /* underflow or denormalized */
285
286 result.parts.exp = 0;
287
288 exp *= -1;
289 if (exp > FLOAT32_FRACTION_SIZE) {
290 /* FIXME: underflow */
291 result.parts.fraction = 0;
292 return result;
293 }
294
295 /* denormalized */
296
297 frac_hi = a.parts.frac_hi;
298 frac_lo = a.parts.frac_lo;
299
300 /* denormalize and set hidden bit */
301 frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
302
303 rshift128(frac_hi, frac_lo,
304 (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
305 &frac_hi, &frac_lo);
306
307 while (exp > 0) {
308 --exp;
309 rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
310 }
311 result.parts.fraction = frac_lo;
312
313 return result;
314 }
315
316 result.parts.exp = exp;
317 frac_hi = a.parts.frac_hi;
318 frac_lo = a.parts.frac_lo;
319 rshift128(frac_hi, frac_lo,
320 (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
321 &frac_hi, &frac_lo);
322 result.parts.fraction = frac_lo;
323 return result;
324}
325
326float64 float128_to_float64(float128 a)
327{
328 float64 result;
329 int32_t exp;
330 uint64_t frac_hi, frac_lo;
331
332 result.parts.sign = a.parts.sign;
333
334 if (is_float128_nan(a)) {
335 result.parts.exp = FLOAT64_MAX_EXPONENT;
336
337 if (is_float128_signan(a)) {
338 /* set first bit of fraction nonzero */
339 result.parts.fraction = FLOAT64_HIDDEN_BIT_MASK >> 1;
340 return result;
341 }
342
343 /* fraction nonzero but its first bit is zero */
344 result.parts.fraction = 0x1;
345 return result;
346 }
347
348 if (is_float128_infinity(a)) {
349 result.parts.fraction = 0;
350 result.parts.exp = FLOAT64_MAX_EXPONENT;
351 return result;
352 }
353
354 exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT64_BIAS;
355
356 if (exp >= FLOAT64_MAX_EXPONENT) {
357 /* FIXME: overflow */
358 result.parts.fraction = 0;
359 result.parts.exp = FLOAT64_MAX_EXPONENT;
360 return result;
361 } else if (exp <= 0) {
362 /* underflow or denormalized */
363
364 result.parts.exp = 0;
365
366 exp *= -1;
367 if (exp > FLOAT64_FRACTION_SIZE) {
368 /* FIXME: underflow */
369 result.parts.fraction = 0;
370 return result;
371 }
372
373 /* denormalized */
374
375 frac_hi = a.parts.frac_hi;
376 frac_lo = a.parts.frac_lo;
377
378 /* denormalize and set hidden bit */
379 frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
380
381 rshift128(frac_hi, frac_lo,
382 (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
383 &frac_hi, &frac_lo);
384
385 while (exp > 0) {
386 --exp;
387 rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
388 }
389 result.parts.fraction = frac_lo;
390
391 return result;
392 }
393
394 result.parts.exp = exp;
395 frac_hi = a.parts.frac_hi;
396 frac_lo = a.parts.frac_lo;
397 rshift128(frac_hi, frac_lo,
398 (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
399 &frac_hi, &frac_lo);
400 result.parts.fraction = frac_lo;
401 return result;
402}
403
404/** Helper procedure for converting float32 to uint32.
405 *
406 * @param a Floating point number in normalized form
407 * (NaNs or Inf are not checked).
408 * @return Converted unsigned integer.
409 */
410static uint32_t _float32_to_uint32_helper(float32 a)
411{
412 uint32_t frac;
413
414 if (a.parts.exp < FLOAT32_BIAS) {
415 /* TODO: rounding */
416 return 0;
417 }
418
419 frac = a.parts.fraction;
420
421 frac |= FLOAT32_HIDDEN_BIT_MASK;
422 /* shift fraction to left so hidden bit will be the most significant bit */
423 frac <<= 32 - FLOAT32_FRACTION_SIZE - 1;
424
425 frac >>= 32 - (a.parts.exp - FLOAT32_BIAS) - 1;
426 if ((a.parts.sign == 1) && (frac != 0)) {
427 frac = ~frac;
428 ++frac;
429 }
430
431 return frac;
432}
433
434/*
435 * FIXME: Im not sure what to return if overflow/underflow happens
436 * - now its the biggest or the smallest int
437 */
438uint32_t float32_to_uint32(float32 a)
439{
440 if (is_float32_nan(a))
441 return UINT32_MAX;
442
443 if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
444 if (a.parts.sign)
445 return UINT32_MIN;
446
447 return UINT32_MAX;
448 }
449
450 return _float32_to_uint32_helper(a);
451}
452
453/*
454 * FIXME: Im not sure what to return if overflow/underflow happens
455 * - now its the biggest or the smallest int
456 */
457int32_t float32_to_int32(float32 a)
458{
459 if (is_float32_nan(a))
460 return INT32_MAX;
461
462 if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
463 if (a.parts.sign)
464 return INT32_MIN;
465
466 return INT32_MAX;
467 }
468
469 return _float32_to_uint32_helper(a);
470}
471
472/** Helper procedure for converting float32 to uint64.
473 *
474 * @param a Floating point number in normalized form
475 * (NaNs or Inf are not checked).
476 * @return Converted unsigned integer.
477 */
478static uint64_t _float32_to_uint64_helper(float32 a)
479{
480 uint64_t frac;
481
482 if (a.parts.exp < FLOAT32_BIAS) {
483 // TODO: rounding
484 return 0;
485 }
486
487 frac = a.parts.fraction;
488
489 frac |= FLOAT32_HIDDEN_BIT_MASK;
490 /* shift fraction to left so hidden bit will be the most significant bit */
491 frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
492
493 frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
494 if ((a.parts.sign == 1) && (frac != 0)) {
495 frac = ~frac;
496 ++frac;
497 }
498
499 return frac;
500}
501
502/*
503 * FIXME: Im not sure what to return if overflow/underflow happens
504 * - now its the biggest or the smallest int
505 */
506uint64_t float32_to_uint64(float32 a)
507{
508 if (is_float32_nan(a))
509 return UINT64_MAX;
510
511 if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
512 if (a.parts.sign)
513 return UINT64_MIN;
514
515 return UINT64_MAX;
516 }
517
518 return _float32_to_uint64_helper(a);
519}
520
521/*
522 * FIXME: Im not sure what to return if overflow/underflow happens
523 * - now its the biggest or the smallest int
524 */
525int64_t float32_to_int64(float32 a)
526{
527 if (is_float32_nan(a))
528 return INT64_MAX;
529
530 if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
531 if (a.parts.sign)
532 return INT64_MIN;
533
534 return INT64_MAX;
535 }
536
537 return _float32_to_uint64_helper(a);
538}
539
540/** Helper procedure for converting float64 to uint64.
541 *
542 * @param a Floating point number in normalized form
543 * (NaNs or Inf are not checked).
544 * @return Converted unsigned integer.
545 */
546static uint64_t _float64_to_uint64_helper(float64 a)
547{
548 uint64_t frac;
549
550 if (a.parts.exp < FLOAT64_BIAS) {
551 // TODO: rounding
552 return 0;
553 }
554
555 frac = a.parts.fraction;
556
557 frac |= FLOAT64_HIDDEN_BIT_MASK;
558 /* shift fraction to left so hidden bit will be the most significant bit */
559 frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
560
561 frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
562 if ((a.parts.sign == 1) && (frac != 0)) {
563 frac = ~frac;
564 ++frac;
565 }
566
567 return frac;
568}
569
570/*
571 * FIXME: Im not sure what to return if overflow/underflow happens
572 * - now its the biggest or the smallest int
573 */
574uint32_t float64_to_uint32(float64 a)
575{
576 if (is_float64_nan(a))
577 return UINT32_MAX;
578
579 if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
580 if (a.parts.sign)
581 return UINT32_MIN;
582
583 return UINT32_MAX;
584 }
585
586 return (uint32_t) _float64_to_uint64_helper(a);
587}
588
589/*
590 * FIXME: Im not sure what to return if overflow/underflow happens
591 * - now its the biggest or the smallest int
592 */
593int32_t float64_to_int32(float64 a)
594{
595 if (is_float64_nan(a))
596 return INT32_MAX;
597
598 if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
599 if (a.parts.sign)
600 return INT32_MIN;
601
602 return INT32_MAX;
603 }
604
605 return (int32_t) _float64_to_uint64_helper(a);
606}
607
608/*
609 * FIXME: Im not sure what to return if overflow/underflow happens
610 * - now its the biggest or the smallest int
611 */
612uint64_t float64_to_uint64(float64 a)
613{
614 if (is_float64_nan(a))
615 return UINT64_MAX;
616
617 if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
618 if (a.parts.sign)
619 return UINT64_MIN;
620
621 return UINT64_MAX;
622 }
623
624 return _float64_to_uint64_helper(a);
625}
626
627/*
628 * FIXME: Im not sure what to return if overflow/underflow happens
629 * - now its the biggest or the smallest int
630 */
631int64_t float64_to_int64(float64 a)
632{
633 if (is_float64_nan(a))
634 return INT64_MAX;
635
636 if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
637 if (a.parts.sign)
638 return INT64_MIN;
639
640 return INT64_MAX;
641 }
642
643 return _float64_to_uint64_helper(a);
644}
645
646/** Helper procedure for converting float128 to uint64.
647 *
648 * @param a Floating point number in normalized form
649 * (NaNs or Inf are not checked).
650 * @return Converted unsigned integer.
651 */
652static uint64_t _float128_to_uint64_helper(float128 a)
653{
654 uint64_t frac_hi, frac_lo;
655
656 if (a.parts.exp < FLOAT128_BIAS) {
657 // TODO: rounding
658 return 0;
659 }
660
661 frac_hi = a.parts.frac_hi;
662 frac_lo = a.parts.frac_lo;
663
664 frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
665 /* shift fraction to left so hidden bit will be the most significant bit */
666 lshift128(frac_hi, frac_lo,
667 (128 - FLOAT128_FRACTION_SIZE - 1), &frac_hi, &frac_lo);
668
669 rshift128(frac_hi, frac_lo,
670 (128 - (a.parts.exp - FLOAT128_BIAS) - 1), &frac_hi, &frac_lo);
671 if ((a.parts.sign == 1) && !eq128(frac_hi, frac_lo, 0x0ll, 0x0ll)) {
672 not128(frac_hi, frac_lo, &frac_hi, &frac_lo);
673 add128(frac_hi, frac_lo, 0x0ll, 0x1ll, &frac_hi, &frac_lo);
674 }
675
676 return frac_lo;
677}
678
679/*
680 * FIXME: Im not sure what to return if overflow/underflow happens
681 * - now its the biggest or the smallest int
682 */
683uint32_t float128_to_uint32(float128 a)
684{
685 if (is_float128_nan(a))
686 return UINT32_MAX;
687
688 if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
689 if (a.parts.sign)
690 return UINT32_MIN;
691
692 return UINT32_MAX;
693 }
694
695 return (uint32_t) _float128_to_uint64_helper(a);
696}
697
698/*
699 * FIXME: Im not sure what to return if overflow/underflow happens
700 * - now its the biggest or the smallest int
701 */
702int32_t float128_to_int32(float128 a)
703{
704 if (is_float128_nan(a))
705 return INT32_MAX;
706
707 if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
708 if (a.parts.sign)
709 return INT32_MIN;
710
711 return INT32_MAX;
712 }
713
714 return (int32_t) _float128_to_uint64_helper(a);
715}
716
717/*
718 * FIXME: Im not sure what to return if overflow/underflow happens
719 * - now its the biggest or the smallest int
720 */
721uint64_t float128_to_uint64(float128 a)
722{
723 if (is_float128_nan(a))
724 return UINT64_MAX;
725
726 if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
727 if (a.parts.sign)
728 return UINT64_MIN;
729
730 return UINT64_MAX;
731 }
732
733 return _float128_to_uint64_helper(a);
734}
735
736/*
737 * FIXME: Im not sure what to return if overflow/underflow happens
738 * - now its the biggest or the smallest int
739 */
740int64_t float128_to_int64(float128 a)
741{
742 if (is_float128_nan(a))
743 return INT64_MAX;
744
745 if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
746 if (a.parts.sign)
747 return INT64_MIN;
748
749 return INT64_MAX;
750 }
751
752 return _float128_to_uint64_helper(a);
753}
754
755float32 uint32_to_float32(uint32_t i)
756{
757 int counter;
758 int32_t exp;
759 float32 result;
760
761 result.parts.sign = 0;
762 result.parts.fraction = 0;
763
764 counter = count_zeroes32(i);
765
766 exp = FLOAT32_BIAS + 32 - counter - 1;
767
768 if (counter == 32) {
769 result.bin = 0;
770 return result;
771 }
772
773 if (counter > 0) {
774 i <<= counter - 1;
775 } else {
776 i >>= 1;
777 }
778
779 round_float32(&exp, &i);
780
781 result.parts.fraction = i >> (32 - FLOAT32_FRACTION_SIZE - 2);
782 result.parts.exp = exp;
783
784 return result;
785}
786
787float32 int32_to_float32(int32_t i)
788{
789 float32 result;
790
791 if (i < 0)
792 result = uint32_to_float32((uint32_t) (-i));
793 else
794 result = uint32_to_float32((uint32_t) i);
795
796 result.parts.sign = i < 0;
797
798 return result;
799}
800
801float32 uint64_to_float32(uint64_t i)
802{
803 int counter;
804 int32_t exp;
805 uint32_t j;
806 float32 result;
807
808 result.parts.sign = 0;
809 result.parts.fraction = 0;
810
811 counter = count_zeroes64(i);
812
813 exp = FLOAT32_BIAS + 64 - counter - 1;
814
815 if (counter == 64) {
816 result.bin = 0;
817 return result;
818 }
819
820 /* Shift all to the first 31 bits (31st will be hidden 1) */
821 if (counter > 33) {
822 i <<= counter - 1 - 32;
823 } else {
824 i >>= 1 + 32 - counter;
825 }
826
827 j = (uint32_t) i;
828 round_float32(&exp, &j);
829
830 result.parts.fraction = j >> (32 - FLOAT32_FRACTION_SIZE - 2);
831 result.parts.exp = exp;
832 return result;
833}
834
835float32 int64_to_float32(int64_t i)
836{
837 float32 result;
838
839 if (i < 0)
840 result = uint64_to_float32((uint64_t) (-i));
841 else
842 result = uint64_to_float32((uint64_t) i);
843
844 result.parts.sign = i < 0;
845
846 return result;
847}
848
849float64 uint32_to_float64(uint32_t i)
850{
851 int counter;
852 int32_t exp;
853 float64 result;
854 uint64_t frac;
855
856 result.parts.sign = 0;
857 result.parts.fraction = 0;
858
859 counter = count_zeroes32(i);
860
861 exp = FLOAT64_BIAS + 32 - counter - 1;
862
863 if (counter == 32) {
864 result.bin = 0;
865 return result;
866 }
867
868 frac = i;
869 frac <<= counter + 32 - 1;
870
871 round_float64(&exp, &frac);
872
873 result.parts.fraction = frac >> (64 - FLOAT64_FRACTION_SIZE - 2);
874 result.parts.exp = exp;
875
876 return result;
877}
878
879float64 int32_to_float64(int32_t i)
880{
881 float64 result;
882
883 if (i < 0)
884 result = uint32_to_float64((uint32_t) (-i));
885 else
886 result = uint32_to_float64((uint32_t) i);
887
888 result.parts.sign = i < 0;
889
890 return result;
891}
892
893
894float64 uint64_to_float64(uint64_t i)
895{
896 int counter;
897 int32_t exp;
898 float64 result;
899
900 result.parts.sign = 0;
901 result.parts.fraction = 0;
902
903 counter = count_zeroes64(i);
904
905 exp = FLOAT64_BIAS + 64 - counter - 1;
906
907 if (counter == 64) {
908 result.bin = 0;
909 return result;
910 }
911
912 if (counter > 0) {
913 i <<= counter - 1;
914 } else {
915 i >>= 1;
916 }
917
918 round_float64(&exp, &i);
919
920 result.parts.fraction = i >> (64 - FLOAT64_FRACTION_SIZE - 2);
921 result.parts.exp = exp;
922 return result;
923}
924
925float64 int64_to_float64(int64_t i)
926{
927 float64 result;
928
929 if (i < 0)
930 result = uint64_to_float64((uint64_t) (-i));
931 else
932 result = uint64_to_float64((uint64_t) i);
933
934 result.parts.sign = i < 0;
935
936 return result;
937}
938
939float128 uint32_to_float128(uint32_t i)
940{
941 int counter;
942 int32_t exp;
943 float128 result;
944 uint64_t frac_hi, frac_lo;
945
946 result.parts.sign = 0;
947 result.parts.frac_hi = 0;
948 result.parts.frac_lo = 0;
949
950 counter = count_zeroes32(i);
951
952 exp = FLOAT128_BIAS + 32 - counter - 1;
953
954 if (counter == 32) {
955 result.bin.hi = 0;
956 result.bin.lo = 0;
957 return result;
958 }
959
960 frac_hi = 0;
961 frac_lo = i;
962 lshift128(frac_hi, frac_lo, (counter + 96 - 1), &frac_hi, &frac_lo);
963
964 round_float128(&exp, &frac_hi, &frac_lo);
965
966 rshift128(frac_hi, frac_lo,
967 (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
968 result.parts.frac_hi = frac_hi;
969 result.parts.frac_lo = frac_lo;
970 result.parts.exp = exp;
971
972 return result;
973}
974
975float128 int32_to_float128(int32_t i)
976{
977 float128 result;
978
979 if (i < 0)
980 result = uint32_to_float128((uint32_t) (-i));
981 else
982 result = uint32_to_float128((uint32_t) i);
983
984 result.parts.sign = i < 0;
985
986 return result;
987}
988
989
990float128 uint64_to_float128(uint64_t i)
991{
992 int counter;
993 int32_t exp;
994 float128 result;
995 uint64_t frac_hi, frac_lo;
996
997 result.parts.sign = 0;
998 result.parts.frac_hi = 0;
999 result.parts.frac_lo = 0;
1000
1001 counter = count_zeroes64(i);
1002
1003 exp = FLOAT128_BIAS + 64 - counter - 1;
1004
1005 if (counter == 64) {
1006 result.bin.hi = 0;
1007 result.bin.lo = 0;
1008 return result;
1009 }
1010
1011 frac_hi = 0;
1012 frac_lo = i;
1013 lshift128(frac_hi, frac_lo, (counter + 64 - 1), &frac_hi, &frac_lo);
1014
1015 round_float128(&exp, &frac_hi, &frac_lo);
1016
1017 rshift128(frac_hi, frac_lo,
1018 (128 - FLOAT128_FRACTION_SIZE - 2), &frac_hi, &frac_lo);
1019 result.parts.frac_hi = frac_hi;
1020 result.parts.frac_lo = frac_lo;
1021 result.parts.exp = exp;
1022
1023 return result;
1024}
1025
1026float128 int64_to_float128(int64_t i)
1027{
1028 float128 result;
1029
1030 if (i < 0)
1031 result = uint64_to_float128((uint64_t) (-i));
1032 else
1033 result = uint64_to_float128((uint64_t) i);
1034
1035 result.parts.sign = i < 0;
1036
1037 return result;
1038}
1039
1040/** @}
1041 */
Note: See TracBrowser for help on using the repository browser.