source: mainline/softfloat/generic/conversion.c@ f37d769

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since f37d769 was f37d769, checked in by Josef Cejka <malyzelenyhnus@…>, 19 years ago

Int32 and int64 → double conversions.

  • Property mode set to 100644
File size: 11.6 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#include "sftypes.h"
30#include "conversion.h"
31#include "comparison.h"
32#include "common.h"
33
34float64 convertFloat32ToFloat64(float32 a)
35{
36 float64 result;
37 __u64 frac;
38
39 result.parts.sign = a.parts.sign;
40 result.parts.fraction = a.parts.fraction;
41 result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE );
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
53 if (result.parts.fraction == 0ll) { /* fix zero */
54 result.parts.exp = 0ll;
55 return result;
56 }
57
58 frac = result.parts.fraction;
59
60 while (!(frac & (0x10000000000000ll))) {
61 frac <<= 1;
62 --result.parts.exp;
63 };
64
65 ++result.parts.exp;
66 result.parts.fraction = frac;
67 };
68
69 return result;
70
71}
72
73float32 convertFloat64ToFloat32(float64 a)
74{
75 float32 result;
76 __s32 exp;
77 __u64 frac;
78
79 result.parts.sign = a.parts.sign;
80
81 if (isFloat64NaN(a)) {
82
83 result.parts.exp = 0xFF;
84
85 if (isFloat64SigNaN(a)) {
86 result.parts.fraction = 0x800000; /* set first bit of fraction nonzero */
87 return result;
88 }
89
90 result.parts.fraction = 0x1; /* fraction nonzero but its first bit is zero */
91 return result;
92 };
93
94 if (isFloat64Infinity(a)) {
95 result.parts.fraction = 0;
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*/
104 result.parts.fraction = 0;
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;
115 if (exp > FLOAT32_FRACTION_SIZE ) {
116 /* FIXME: underflow */
117 result.parts.fraction = 0;
118 return result;
119 };
120
121 /* denormalized */
122
123 frac = a.parts.fraction;
124 frac |= 0x10000000000000ll; /* denormalize and set hidden bit */
125
126 frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
127
128 while (exp > 0) {
129 --exp;
130 frac >>= 1;
131 };
132 result.parts.fraction = frac;
133
134 return result;
135 };
136
137 result.parts.exp = exp;
138 result.parts.fraction = a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
139 return result;
140}
141
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 */
147static __u32 _float32_to_uint32_helper(float32 a)
148{
149 __u32 frac;
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 */
175__u32 float32_to_uint32(float32 a)
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 */
195__s32 float32_to_int32(float32 a)
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
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 */
215static __u64 _float64_to_uint64_helper(float64 a)
216{
217 __u64 frac;
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;
229
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 */
243__u64 float64_to_uint64(float64 a)
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 */
263__s64 float64_to_int64(float64 a)
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 */
286static __u64 _float32_to_uint64_helper(float32 a)
287{
288 __u64 frac;
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 */
314__u64 float32_to_uint64(float32 a)
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 */
334__s64 float32_to_int64(float32 a)
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 */
354__u32 float64_to_uint32(float64 a)
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
367 return (__u32)_float64_to_uint64_helper(a);
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 */
374__s32 float64_to_int32(float64 a)
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 }
386 return (__s32)_float64_to_uint64_helper(a);
387}
388
389/** Convert unsigned integer to float32
390 *
391 *
392 */
393float32 uint32_to_float32(__u32 i)
394{
395 int counter;
396 __s32 exp;
397 float32 result;
398
399 result.parts.sign = 0;
400 result.parts.fraction = 0;
401
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
425float32 int32_to_float32(__s32 i)
426{
427 float32 result;
428
429 if (i < 0) {
430 result = uint32_to_float32((__u32)(-i));
431 } else {
432 result = uint32_to_float32((__u32)i);
433 }
434
435 result.parts.sign = i < 0;
436
437 return result;
438}
439
440
441float32 uint64_to_float32(__u64 i)
442{
443 int counter;
444 __s32 exp;
445 float32 result;
446
447 result.parts.sign = 0;
448 result.parts.fraction = 0;
449
450 counter = countZeroes64(i);
451
452 exp = FLOAT32_BIAS + 64 - counter - 1;
453
454 if (counter == 64) {
455 result.binary = 0;
456 return result;
457 }
458
459 /* Shift all to the first 31 bits (31. will be hidden 1)*/
460 if (counter > 33) {
461 i <<= counter - 1 - 32;
462 } else {
463 i >>= 1 + 32 - counter;
464 }
465
466 roundFloat32(&exp, &i);
467
468 result.parts.fraction = i >> 7;
469 result.parts.exp = exp;
470 return result;
471}
472
473float32 int64_to_float32(__s64 i)
474{
475 float32 result;
476
477 if (i < 0) {
478 result = uint64_to_float32((__u64)(-i));
479 } else {
480 result = uint64_to_float32((__u64)i);
481 }
482
483 result.parts.sign = i < 0;
484
485 return result;
486}
487
488/** Convert unsigned integer to float64
489 *
490 *
491 */
492float64 uint32_to_float64(__u32 i)
493{
494 int counter;
495 __s32 exp;
496 float64 result;
497 __u64 frac;
498
499 result.parts.sign = 0;
500 result.parts.fraction = 0;
501
502 counter = countZeroes32(i);
503
504 exp = FLOAT64_BIAS + 32 - counter - 1;
505
506 if (counter == 32) {
507 result.binary = 0;
508 return result;
509 }
510
511 frac = i;
512 frac <<= counter + 32 - 1;
513
514 roundFloat64(&exp, &frac);
515
516 result.parts.fraction = frac >> 10;
517 result.parts.exp = exp;
518
519 return result;
520}
521
522float64 int32_to_float64(__s32 i)
523{
524 float64 result;
525
526 if (i < 0) {
527 result = uint32_to_float64((__u32)(-i));
528 } else {
529 result = uint32_to_float64((__u32)i);
530 }
531
532 result.parts.sign = i < 0;
533
534 return result;
535}
536
537
538float64 uint64_to_float64(__u64 i)
539{
540 int counter;
541 __s32 exp;
542 float64 result;
543
544 result.parts.sign = 0;
545 result.parts.fraction = 0;
546
547 counter = countZeroes64(i);
548
549 exp = FLOAT64_BIAS + 64 - counter - 1;
550
551 if (counter == 64) {
552 result.binary = 0;
553 return result;
554 }
555
556 if (counter > 0) {
557 i <<= counter - 1;
558 } else {
559 i >>= 1;
560 }
561
562 roundFloat64(&exp, &i);
563
564 result.parts.fraction = i >> 10;
565 result.parts.exp = exp;
566 return result;
567}
568
569float64 int64_to_float64(__s64 i)
570{
571 float64 result;
572
573 if (i < 0) {
574 result = uint64_to_float64((__u64)(-i));
575 } else {
576 result = uint64_to_float64((__u64)i);
577 }
578
579 result.parts.sign = i < 0;
580
581 return result;
582}
583
584
Note: See TracBrowser for help on using the repository browser.