source: mainline/uspace/lib/softfloat/generic/conversion.c@ 88d5c1e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 88d5c1e 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
RevLine 
[b5440cf]1/*
[df4ed85]2 * Copyright (c) 2005 Josef Cejka
[c67aff2]3 * Copyright (c) 2011 Petr Koupy
[b5440cf]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
[9539be6]30/** @addtogroup softfloat
[846848a6]31 * @{
32 */
[c67aff2]33/** @file Conversion of precision and conversion between integers and floats.
[846848a6]34 */
35
[c67aff2]36#include <sftypes.h>
37#include <conversion.h>
38#include <comparison.h>
39#include <common.h>
[feef1cd]40
[88d5c1e]41float64 float32_to_float64(float32 a)
[feef1cd]42{
43 float64 result;
[aa59fa0]44 uint64_t frac;
[feef1cd]45
46 result.parts.sign = a.parts.sign;
[1266543]47 result.parts.fraction = a.parts.fraction;
[9539be6]48 result.parts.fraction <<= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
[feef1cd]49
[88d5c1e]50 if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
[c67aff2]51 result.parts.exp = FLOAT64_MAX_EXPONENT;
[88d5c1e]52 // TODO; check if its correct for SigNaNs
[feef1cd]53 return result;
[c67aff2]54 }
[feef1cd]55
[9539be6]56 result.parts.exp = a.parts.exp + ((int) FLOAT64_BIAS - FLOAT32_BIAS);
[feef1cd]57 if (a.parts.exp == 0) {
58 /* normalize denormalized numbers */
[88d5c1e]59
[c67aff2]60 if (result.parts.fraction == 0) { /* fix zero */
61 result.parts.exp = 0;
[feef1cd]62 return result;
63 }
64
[1266543]65 frac = result.parts.fraction;
[feef1cd]66
[c67aff2]67 while (!(frac & FLOAT64_HIDDEN_BIT_MASK)) {
[1266543]68 frac <<= 1;
[feef1cd]69 --result.parts.exp;
[c67aff2]70 }
[56a39dde]71
72 ++result.parts.exp;
[1266543]73 result.parts.fraction = frac;
[c67aff2]74 }
[feef1cd]75
76 return result;
[c67aff2]77}
78
[88d5c1e]79float128 float32_to_float128(float32 a)
[c67aff2]80{
81 float128 result;
82 uint64_t frac_hi, frac_lo;
83 uint64_t tmp_hi, tmp_lo;
[88d5c1e]84
[c67aff2]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;
[88d5c1e]93
94 if ((is_float32_infinity(a)) || (is_float32_nan(a))) {
[c67aff2]95 result.parts.exp = FLOAT128_MAX_EXPONENT;
[88d5c1e]96 // TODO; check if its correct for SigNaNs
[c67aff2]97 return result;
98 }
[88d5c1e]99
[c67aff2]100 result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT32_BIAS);
101 if (a.parts.exp == 0) {
102 /* normalize denormalized numbers */
[88d5c1e]103
[c67aff2]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 }
[88d5c1e]109
[c67aff2]110 frac_hi = result.parts.frac_hi;
111 frac_lo = result.parts.frac_lo;
[88d5c1e]112
[c67aff2]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 }
[88d5c1e]120
[c67aff2]121 ++result.parts.exp;
122 result.parts.frac_hi = frac_hi;
123 result.parts.frac_lo = frac_lo;
124 }
[88d5c1e]125
[c67aff2]126 return result;
127}
128
[88d5c1e]129float128 float64_to_float128(float64 a)
[c67aff2]130{
131 float128 result;
132 uint64_t frac_hi, frac_lo;
133 uint64_t tmp_hi, tmp_lo;
[88d5c1e]134
[c67aff2]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;
[88d5c1e]143
144 if ((is_float64_infinity(a)) || (is_float64_nan(a))) {
[c67aff2]145 result.parts.exp = FLOAT128_MAX_EXPONENT;
[88d5c1e]146 // TODO; check if its correct for SigNaNs
[c67aff2]147 return result;
148 }
[88d5c1e]149
[c67aff2]150 result.parts.exp = a.parts.exp + ((int) FLOAT128_BIAS - FLOAT64_BIAS);
151 if (a.parts.exp == 0) {
152 /* normalize denormalized numbers */
[88d5c1e]153
[c67aff2]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 }
[88d5c1e]159
[c67aff2]160 frac_hi = result.parts.frac_hi;
161 frac_lo = result.parts.frac_lo;
[88d5c1e]162
[c67aff2]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 }
[88d5c1e]170
[c67aff2]171 ++result.parts.exp;
172 result.parts.frac_hi = frac_hi;
173 result.parts.frac_lo = frac_lo;
174 }
[88d5c1e]175
[c67aff2]176 return result;
[afffa1e]177}
[feef1cd]178
[88d5c1e]179float32 float64_to_float32(float64 a)
[feef1cd]180{
181 float32 result;
[aa59fa0]182 int32_t exp;
183 uint64_t frac;
[feef1cd]184
185 result.parts.sign = a.parts.sign;
186
[88d5c1e]187 if (is_float64_nan(a)) {
[c67aff2]188 result.parts.exp = FLOAT32_MAX_EXPONENT;
[feef1cd]189
[88d5c1e]190 if (is_float64_signan(a)) {
[c67aff2]191 /* set first bit of fraction nonzero */
192 result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
[feef1cd]193 return result;
194 }
[88d5c1e]195
[c67aff2]196 /* fraction nonzero but its first bit is zero */
197 result.parts.fraction = 0x1;
[feef1cd]198 return result;
[c67aff2]199 }
[88d5c1e]200
201 if (is_float64_infinity(a)) {
[1266543]202 result.parts.fraction = 0;
[c67aff2]203 result.parts.exp = FLOAT32_MAX_EXPONENT;
[feef1cd]204 return result;
[c67aff2]205 }
[88d5c1e]206
[c67aff2]207 exp = (int) a.parts.exp - FLOAT64_BIAS + FLOAT32_BIAS;
[feef1cd]208
[c67aff2]209 if (exp >= FLOAT32_MAX_EXPONENT) {
210 /* FIXME: overflow */
[1266543]211 result.parts.fraction = 0;
[c67aff2]212 result.parts.exp = FLOAT32_MAX_EXPONENT;
[feef1cd]213 return result;
[c67aff2]214 } else if (exp <= 0) {
[feef1cd]215 /* underflow or denormalized */
216
217 result.parts.exp = 0;
218
219 exp *= -1;
[c67aff2]220 if (exp > FLOAT32_FRACTION_SIZE) {
[feef1cd]221 /* FIXME: underflow */
[1266543]222 result.parts.fraction = 0;
[feef1cd]223 return result;
[c67aff2]224 }
[feef1cd]225
226 /* denormalized */
227
[1266543]228 frac = a.parts.fraction;
[c67aff2]229 frac |= FLOAT64_HIDDEN_BIT_MASK; /* denormalize and set hidden bit */
[feef1cd]230
[1266543]231 frac >>= (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1);
[56a39dde]232
[feef1cd]233 while (exp > 0) {
234 --exp;
[1266543]235 frac >>= 1;
[c67aff2]236 }
[1266543]237 result.parts.fraction = frac;
[feef1cd]238
239 return result;
[c67aff2]240 }
[88d5c1e]241
[c67aff2]242 result.parts.exp = exp;
243 result.parts.fraction =
244 a.parts.fraction >> (FLOAT64_FRACTION_SIZE - FLOAT32_FRACTION_SIZE);
245 return result;
246}
247
[88d5c1e]248float32 float128_to_float32(float128 a)
[c67aff2]249{
250 float32 result;
251 int32_t exp;
252 uint64_t frac_hi, frac_lo;
[88d5c1e]253
[c67aff2]254 result.parts.sign = a.parts.sign;
[88d5c1e]255
256 if (is_float128_nan(a)) {
[c67aff2]257 result.parts.exp = FLOAT32_MAX_EXPONENT;
[88d5c1e]258
259 if (is_float128_signan(a)) {
[c67aff2]260 /* set first bit of fraction nonzero */
261 result.parts.fraction = FLOAT32_HIDDEN_BIT_MASK >> 1;
262 return result;
263 }
[88d5c1e]264
[c67aff2]265 /* fraction nonzero but its first bit is zero */
266 result.parts.fraction = 0x1;
267 return result;
268 }
[88d5c1e]269
270 if (is_float128_infinity(a)) {
[c67aff2]271 result.parts.fraction = 0;
272 result.parts.exp = FLOAT32_MAX_EXPONENT;
273 return result;
274 }
[88d5c1e]275
[c67aff2]276 exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT32_BIAS;
[88d5c1e]277
[c67aff2]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 */
[88d5c1e]285
[c67aff2]286 result.parts.exp = 0;
[88d5c1e]287
[c67aff2]288 exp *= -1;
289 if (exp > FLOAT32_FRACTION_SIZE) {
290 /* FIXME: underflow */
291 result.parts.fraction = 0;
292 return result;
293 }
[88d5c1e]294
[c67aff2]295 /* denormalized */
[88d5c1e]296
[c67aff2]297 frac_hi = a.parts.frac_hi;
298 frac_lo = a.parts.frac_lo;
[88d5c1e]299
[c67aff2]300 /* denormalize and set hidden bit */
301 frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
[88d5c1e]302
[c67aff2]303 rshift128(frac_hi, frac_lo,
304 (FLOAT128_FRACTION_SIZE - FLOAT32_FRACTION_SIZE + 1),
305 &frac_hi, &frac_lo);
[88d5c1e]306
[c67aff2]307 while (exp > 0) {
308 --exp;
309 rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
310 }
311 result.parts.fraction = frac_lo;
[88d5c1e]312
[c67aff2]313 return result;
314 }
[88d5c1e]315
[feef1cd]316 result.parts.exp = exp;
[c67aff2]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;
[feef1cd]323 return result;
[afffa1e]324}
325
[88d5c1e]326float64 float128_to_float64(float128 a)
[c67aff2]327{
328 float64 result;
329 int32_t exp;
330 uint64_t frac_hi, frac_lo;
[88d5c1e]331
[c67aff2]332 result.parts.sign = a.parts.sign;
[88d5c1e]333
334 if (is_float128_nan(a)) {
[c67aff2]335 result.parts.exp = FLOAT64_MAX_EXPONENT;
[88d5c1e]336
337 if (is_float128_signan(a)) {
[c67aff2]338 /* set first bit of fraction nonzero */
339 result.parts.fraction = FLOAT64_HIDDEN_BIT_MASK >> 1;
340 return result;
341 }
[88d5c1e]342
[c67aff2]343 /* fraction nonzero but its first bit is zero */
344 result.parts.fraction = 0x1;
345 return result;
346 }
[88d5c1e]347
348 if (is_float128_infinity(a)) {
[c67aff2]349 result.parts.fraction = 0;
350 result.parts.exp = FLOAT64_MAX_EXPONENT;
351 return result;
352 }
[88d5c1e]353
[c67aff2]354 exp = (int) a.parts.exp - FLOAT128_BIAS + FLOAT64_BIAS;
[88d5c1e]355
[c67aff2]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 */
[88d5c1e]363
[c67aff2]364 result.parts.exp = 0;
[88d5c1e]365
[c67aff2]366 exp *= -1;
367 if (exp > FLOAT64_FRACTION_SIZE) {
368 /* FIXME: underflow */
369 result.parts.fraction = 0;
370 return result;
371 }
[88d5c1e]372
[c67aff2]373 /* denormalized */
[88d5c1e]374
[c67aff2]375 frac_hi = a.parts.frac_hi;
376 frac_lo = a.parts.frac_lo;
[88d5c1e]377
[c67aff2]378 /* denormalize and set hidden bit */
379 frac_hi |= FLOAT128_HIDDEN_BIT_MASK_HI;
[88d5c1e]380
[c67aff2]381 rshift128(frac_hi, frac_lo,
382 (FLOAT128_FRACTION_SIZE - FLOAT64_FRACTION_SIZE + 1),
383 &frac_hi, &frac_lo);
[88d5c1e]384
[c67aff2]385 while (exp > 0) {
386 --exp;
387 rshift128(frac_hi, frac_lo, 1, &frac_hi, &frac_lo);
388 }
389 result.parts.fraction = frac_lo;
[88d5c1e]390
[c67aff2]391 return result;
392 }
[88d5c1e]393
[c67aff2]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
[88d5c1e]404/** Helper procedure for converting float32 to uint32.
[c67aff2]405 *
406 * @param a Floating point number in normalized form
407 * (NaNs or Inf are not checked).
408 * @return Converted unsigned integer.
[afffa1e]409 */
[aa59fa0]410static uint32_t _float32_to_uint32_helper(float32 a)
[afffa1e]411{
[aa59fa0]412 uint32_t frac;
[afffa1e]413
414 if (a.parts.exp < FLOAT32_BIAS) {
[c67aff2]415 /* TODO: rounding */
[afffa1e]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;
[88d5c1e]424
[afffa1e]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
[88d5c1e]434/*
435 * FIXME: Im not sure what to return if overflow/underflow happens
436 * - now its the biggest or the smallest int
437 */
[aa59fa0]438uint32_t float32_to_uint32(float32 a)
[afffa1e]439{
[88d5c1e]440 if (is_float32_nan(a))
[9539be6]441 return UINT32_MAX;
[afffa1e]442
[88d5c1e]443 if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
[9539be6]444 if (a.parts.sign)
445 return UINT32_MIN;
446
447 return UINT32_MAX;
[afffa1e]448 }
449
[9539be6]450 return _float32_to_uint32_helper(a);
[afffa1e]451}
452
[88d5c1e]453/*
454 * FIXME: Im not sure what to return if overflow/underflow happens
455 * - now its the biggest or the smallest int
456 */
[aa59fa0]457int32_t float32_to_int32(float32 a)
[afffa1e]458{
[88d5c1e]459 if (is_float32_nan(a))
[9539be6]460 return INT32_MAX;
[afffa1e]461
[88d5c1e]462 if (is_float32_infinity(a) || (a.parts.exp >= (32 + FLOAT32_BIAS))) {
[9539be6]463 if (a.parts.sign)
464 return INT32_MIN;
465
466 return INT32_MAX;
[afffa1e]467 }
[9539be6]468
[afffa1e]469 return _float32_to_uint32_helper(a);
[9539be6]470}
[afffa1e]471
[88d5c1e]472/** Helper procedure for converting float32 to uint64.
[c67aff2]473 *
474 * @param a Floating point number in normalized form
475 * (NaNs or Inf are not checked).
476 * @return Converted unsigned integer.
[a82695c]477 */
[c67aff2]478static uint64_t _float32_to_uint64_helper(float32 a)
[a82695c]479{
[aa59fa0]480 uint64_t frac;
[88d5c1e]481
[c67aff2]482 if (a.parts.exp < FLOAT32_BIAS) {
[88d5c1e]483 // TODO: rounding
[a82695c]484 return 0;
485 }
[88d5c1e]486
[a82695c]487 frac = a.parts.fraction;
[88d5c1e]488
[c67aff2]489 frac |= FLOAT32_HIDDEN_BIT_MASK;
[a82695c]490 /* shift fraction to left so hidden bit will be the most significant bit */
[c67aff2]491 frac <<= 64 - FLOAT32_FRACTION_SIZE - 1;
[88d5c1e]492
[c67aff2]493 frac >>= 64 - (a.parts.exp - FLOAT32_BIAS) - 1;
[a82695c]494 if ((a.parts.sign == 1) && (frac != 0)) {
495 frac = ~frac;
496 ++frac;
497 }
[88d5c1e]498
[a82695c]499 return frac;
500}
501
[88d5c1e]502/*
[c67aff2]503 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]504 * - now its the biggest or the smallest int
[c67aff2]505 */
506uint64_t float32_to_uint64(float32 a)
[a82695c]507{
[88d5c1e]508 if (is_float32_nan(a))
[9539be6]509 return UINT64_MAX;
[88d5c1e]510
511 if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
[9539be6]512 if (a.parts.sign)
513 return UINT64_MIN;
[88d5c1e]514
[9539be6]515 return UINT64_MAX;
[a82695c]516 }
[88d5c1e]517
[c67aff2]518 return _float32_to_uint64_helper(a);
[a82695c]519}
520
[88d5c1e]521/*
[c67aff2]522 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]523 * - now its the biggest or the smallest int
[c67aff2]524 */
525int64_t float32_to_int64(float32 a)
[a82695c]526{
[88d5c1e]527 if (is_float32_nan(a))
[9539be6]528 return INT64_MAX;
[88d5c1e]529
530 if (is_float32_infinity(a) || (a.parts.exp >= (64 + FLOAT32_BIAS))) {
[9539be6]531 if (a.parts.sign)
532 return INT64_MIN;
[88d5c1e]533
[9539be6]534 return INT64_MAX;
[a82695c]535 }
[88d5c1e]536
[c67aff2]537 return _float32_to_uint64_helper(a);
538}
[a82695c]539
[88d5c1e]540/** Helper procedure for converting float64 to uint64.
[c67aff2]541 *
542 * @param a Floating point number in normalized form
543 * (NaNs or Inf are not checked).
544 * @return Converted unsigned integer.
[a82695c]545 */
[c67aff2]546static uint64_t _float64_to_uint64_helper(float64 a)
[a82695c]547{
[aa59fa0]548 uint64_t frac;
[88d5c1e]549
[c67aff2]550 if (a.parts.exp < FLOAT64_BIAS) {
[88d5c1e]551 // TODO: rounding
[a82695c]552 return 0;
553 }
[88d5c1e]554
[a82695c]555 frac = a.parts.fraction;
[88d5c1e]556
[c67aff2]557 frac |= FLOAT64_HIDDEN_BIT_MASK;
[a82695c]558 /* shift fraction to left so hidden bit will be the most significant bit */
[c67aff2]559 frac <<= 64 - FLOAT64_FRACTION_SIZE - 1;
[88d5c1e]560
[c67aff2]561 frac >>= 64 - (a.parts.exp - FLOAT64_BIAS) - 1;
[a82695c]562 if ((a.parts.sign == 1) && (frac != 0)) {
563 frac = ~frac;
564 ++frac;
565 }
[88d5c1e]566
[a82695c]567 return frac;
568}
569
[c67aff2]570/*
571 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]572 * - now its the biggest or the smallest int
[c67aff2]573 */
574uint32_t float64_to_uint32(float64 a)
575{
[88d5c1e]576 if (is_float64_nan(a))
[c67aff2]577 return UINT32_MAX;
[88d5c1e]578
579 if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
[c67aff2]580 if (a.parts.sign)
581 return UINT32_MIN;
[88d5c1e]582
[c67aff2]583 return UINT32_MAX;
584 }
[88d5c1e]585
[c67aff2]586 return (uint32_t) _float64_to_uint64_helper(a);
587}
588
589/*
590 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]591 * - now its the biggest or the smallest int
[c67aff2]592 */
593int32_t float64_to_int32(float64 a)
594{
[88d5c1e]595 if (is_float64_nan(a))
[c67aff2]596 return INT32_MAX;
[88d5c1e]597
598 if (is_float64_infinity(a) || (a.parts.exp >= (32 + FLOAT64_BIAS))) {
[c67aff2]599 if (a.parts.sign)
600 return INT32_MIN;
[88d5c1e]601
[c67aff2]602 return INT32_MAX;
603 }
[88d5c1e]604
[c67aff2]605 return (int32_t) _float64_to_uint64_helper(a);
606}
607
[88d5c1e]608/*
[a82695c]609 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]610 * - now its the biggest or the smallest int
611 */
[c67aff2]612uint64_t float64_to_uint64(float64 a)
[a82695c]613{
[88d5c1e]614 if (is_float64_nan(a))
[9539be6]615 return UINT64_MAX;
[a82695c]616
[88d5c1e]617 if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
[9539be6]618 if (a.parts.sign)
619 return UINT64_MIN;
620
621 return UINT64_MAX;
[a82695c]622 }
623
[c67aff2]624 return _float64_to_uint64_helper(a);
[a82695c]625}
626
[88d5c1e]627/*
[a82695c]628 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]629 * - now its the biggest or the smallest int
630 */
[c67aff2]631int64_t float64_to_int64(float64 a)
[a82695c]632{
[88d5c1e]633 if (is_float64_nan(a))
[9539be6]634 return INT64_MAX;
[a82695c]635
[88d5c1e]636 if (is_float64_infinity(a) || (a.parts.exp >= (64 + FLOAT64_BIAS))) {
[9539be6]637 if (a.parts.sign)
638 return INT64_MIN;
639
640 return INT64_MAX;
[a82695c]641 }
[9539be6]642
[c67aff2]643 return _float64_to_uint64_helper(a);
[9539be6]644}
[a82695c]645
[88d5c1e]646/** Helper procedure for converting float128 to uint64.
[c67aff2]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;
[88d5c1e]655
[c67aff2]656 if (a.parts.exp < FLOAT128_BIAS) {
[88d5c1e]657 // TODO: rounding
[c67aff2]658 return 0;
659 }
[88d5c1e]660
[c67aff2]661 frac_hi = a.parts.frac_hi;
662 frac_lo = a.parts.frac_lo;
[88d5c1e]663
[c67aff2]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);
[88d5c1e]668
[c67aff2]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 }
[88d5c1e]675
[c67aff2]676 return frac_lo;
677}
678
679/*
680 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]681 * - now its the biggest or the smallest int
[c67aff2]682 */
683uint32_t float128_to_uint32(float128 a)
[a82695c]684{
[88d5c1e]685 if (is_float128_nan(a))
[9539be6]686 return UINT32_MAX;
[88d5c1e]687
688 if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
[9539be6]689 if (a.parts.sign)
690 return UINT32_MIN;
[88d5c1e]691
[9539be6]692 return UINT32_MAX;
[a82695c]693 }
[88d5c1e]694
[c67aff2]695 return (uint32_t) _float128_to_uint64_helper(a);
[a82695c]696}
697
[c67aff2]698/*
699 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]700 * - now its the biggest or the smallest int
[c67aff2]701 */
702int32_t float128_to_int32(float128 a)
[a82695c]703{
[88d5c1e]704 if (is_float128_nan(a))
[9539be6]705 return INT32_MAX;
[88d5c1e]706
707 if (is_float128_infinity(a) || (a.parts.exp >= (32 + FLOAT128_BIAS))) {
[9539be6]708 if (a.parts.sign)
709 return INT32_MIN;
[88d5c1e]710
[9539be6]711 return INT32_MAX;
[a82695c]712 }
[88d5c1e]713
[c67aff2]714 return (int32_t) _float128_to_uint64_helper(a);
[9539be6]715}
[a82695c]716
[c67aff2]717/*
718 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]719 * - now its the biggest or the smallest int
[c67aff2]720 */
721uint64_t float128_to_uint64(float128 a)
722{
[88d5c1e]723 if (is_float128_nan(a))
[c67aff2]724 return UINT64_MAX;
[88d5c1e]725
726 if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
[c67aff2]727 if (a.parts.sign)
728 return UINT64_MIN;
[88d5c1e]729
[c67aff2]730 return UINT64_MAX;
731 }
[88d5c1e]732
[c67aff2]733 return _float128_to_uint64_helper(a);
734}
735
736/*
737 * FIXME: Im not sure what to return if overflow/underflow happens
[88d5c1e]738 * - now its the biggest or the smallest int
[1d83419]739 */
[c67aff2]740int64_t float128_to_int64(float128 a)
741{
[88d5c1e]742 if (is_float128_nan(a))
[c67aff2]743 return INT64_MAX;
[88d5c1e]744
745 if (is_float128_infinity(a) || (a.parts.exp >= (64 + FLOAT128_BIAS))) {
[c67aff2]746 if (a.parts.sign)
747 return INT64_MIN;
[88d5c1e]748
[c67aff2]749 return INT64_MAX;
750 }
[88d5c1e]751
[c67aff2]752 return _float128_to_uint64_helper(a);
753}
754
[aa59fa0]755float32 uint32_to_float32(uint32_t i)
[1d83419]756{
757 int counter;
[aa59fa0]758 int32_t exp;
[1d83419]759 float32 result;
760
761 result.parts.sign = 0;
762 result.parts.fraction = 0;
[88d5c1e]763
764 counter = count_zeroes32(i);
765
[1d83419]766 exp = FLOAT32_BIAS + 32 - counter - 1;
767
768 if (counter == 32) {
[88d5c1e]769 result.bin = 0;
[1d83419]770 return result;
771 }
772
773 if (counter > 0) {
774 i <<= counter - 1;
775 } else {
776 i >>= 1;
777 }
[88d5c1e]778
779 round_float32(&exp, &i);
780
[c67aff2]781 result.parts.fraction = i >> (32 - FLOAT32_FRACTION_SIZE - 2);
[1d83419]782 result.parts.exp = exp;
[88d5c1e]783
[1d83419]784 return result;
785}
786
[88d5c1e]787float32 int32_to_float32(int32_t i)
[1d83419]788{
789 float32 result;
[88d5c1e]790
791 if (i < 0)
[c67aff2]792 result = uint32_to_float32((uint32_t) (-i));
[88d5c1e]793 else
[c67aff2]794 result = uint32_to_float32((uint32_t) i);
[1d83419]795
796 result.parts.sign = i < 0;
[88d5c1e]797
798 return result;
[1d83419]799}
800
[88d5c1e]801float32 uint64_to_float32(uint64_t i)
[1d83419]802{
[ba5870d]803 int counter;
[aa59fa0]804 int32_t exp;
[e591928]805 uint32_t j;
[ba5870d]806 float32 result;
807
808 result.parts.sign = 0;
809 result.parts.fraction = 0;
[88d5c1e]810
811 counter = count_zeroes64(i);
812
[ba5870d]813 exp = FLOAT32_BIAS + 64 - counter - 1;
814
815 if (counter == 64) {
[88d5c1e]816 result.bin = 0;
[ba5870d]817 return result;
818 }
819
[c67aff2]820 /* Shift all to the first 31 bits (31st will be hidden 1) */
[ba5870d]821 if (counter > 33) {
822 i <<= counter - 1 - 32;
823 } else {
824 i >>= 1 + 32 - counter;
825 }
[aa59fa0]826
[c67aff2]827 j = (uint32_t) i;
[88d5c1e]828 round_float32(&exp, &j);
829
[c67aff2]830 result.parts.fraction = j >> (32 - FLOAT32_FRACTION_SIZE - 2);
[ba5870d]831 result.parts.exp = exp;
832 return result;
[1d83419]833}
834
[88d5c1e]835float32 int64_to_float32(int64_t i)
[1d83419]836{
837 float32 result;
[88d5c1e]838
839 if (i < 0)
[c67aff2]840 result = uint64_to_float32((uint64_t) (-i));
[88d5c1e]841 else
[c67aff2]842 result = uint64_to_float32((uint64_t) i);
[1d83419]843
844 result.parts.sign = i < 0;
[88d5c1e]845
846 return result;
[1d83419]847}
[f37d769]848
[aa59fa0]849float64 uint32_to_float64(uint32_t i)
[f37d769]850{
851 int counter;
[aa59fa0]852 int32_t exp;
[f37d769]853 float64 result;
[aa59fa0]854 uint64_t frac;
[f37d769]855
856 result.parts.sign = 0;
857 result.parts.fraction = 0;
[88d5c1e]858
859 counter = count_zeroes32(i);
860
[f37d769]861 exp = FLOAT64_BIAS + 32 - counter - 1;
862
863 if (counter == 32) {
[88d5c1e]864 result.bin = 0;
[f37d769]865 return result;
866 }
867
868 frac = i;
[88d5c1e]869 frac <<= counter + 32 - 1;
870
871 round_float64(&exp, &frac);
872
[c67aff2]873 result.parts.fraction = frac >> (64 - FLOAT64_FRACTION_SIZE - 2);
[f37d769]874 result.parts.exp = exp;
[88d5c1e]875
[f37d769]876 return result;
877}
878
[88d5c1e]879float64 int32_to_float64(int32_t i)
[f37d769]880{
881 float64 result;
[88d5c1e]882
883 if (i < 0)
[c67aff2]884 result = uint32_to_float64((uint32_t) (-i));
[88d5c1e]885 else
[c67aff2]886 result = uint32_to_float64((uint32_t) i);
[f37d769]887
888 result.parts.sign = i < 0;
[88d5c1e]889
890 return result;
[f37d769]891}
892
893
[88d5c1e]894float64 uint64_to_float64(uint64_t i)
[f37d769]895{
896 int counter;
[aa59fa0]897 int32_t exp;
[f37d769]898 float64 result;
899
900 result.parts.sign = 0;
901 result.parts.fraction = 0;
[88d5c1e]902
903 counter = count_zeroes64(i);
904
[f37d769]905 exp = FLOAT64_BIAS + 64 - counter - 1;
906
907 if (counter == 64) {
[88d5c1e]908 result.bin = 0;
[f37d769]909 return result;
910 }
911
912 if (counter > 0) {
913 i <<= counter - 1;
914 } else {
915 i >>= 1;
916 }
[88d5c1e]917
918 round_float64(&exp, &i);
919
[c67aff2]920 result.parts.fraction = i >> (64 - FLOAT64_FRACTION_SIZE - 2);
[f37d769]921 result.parts.exp = exp;
922 return result;
923}
924
[88d5c1e]925float64 int64_to_float64(int64_t i)
[f37d769]926{
927 float64 result;
[88d5c1e]928
929 if (i < 0)
[c67aff2]930 result = uint64_to_float64((uint64_t) (-i));
[88d5c1e]931 else
[c67aff2]932 result = uint64_to_float64((uint64_t) i);
[f37d769]933
934 result.parts.sign = i < 0;
[88d5c1e]935
936 return result;
[f37d769]937}
938
[c67aff2]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;
[88d5c1e]945
[c67aff2]946 result.parts.sign = 0;
947 result.parts.frac_hi = 0;
948 result.parts.frac_lo = 0;
[88d5c1e]949
950 counter = count_zeroes32(i);
951
[c67aff2]952 exp = FLOAT128_BIAS + 32 - counter - 1;
[88d5c1e]953
[c67aff2]954 if (counter == 32) {
[88d5c1e]955 result.bin.hi = 0;
956 result.bin.lo = 0;
[c67aff2]957 return result;
958 }
[88d5c1e]959
[c67aff2]960 frac_hi = 0;
961 frac_lo = i;
962 lshift128(frac_hi, frac_lo, (counter + 96 - 1), &frac_hi, &frac_lo);
[88d5c1e]963
964 round_float128(&exp, &frac_hi, &frac_lo);
965
[c67aff2]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;
[88d5c1e]971
[c67aff2]972 return result;
973}
974
975float128 int32_to_float128(int32_t i)
976{
977 float128 result;
[88d5c1e]978
979 if (i < 0)
[c67aff2]980 result = uint32_to_float128((uint32_t) (-i));
[88d5c1e]981 else
[c67aff2]982 result = uint32_to_float128((uint32_t) i);
[88d5c1e]983
[c67aff2]984 result.parts.sign = i < 0;
[88d5c1e]985
986 return result;
[c67aff2]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;
[88d5c1e]996
[c67aff2]997 result.parts.sign = 0;
998 result.parts.frac_hi = 0;
999 result.parts.frac_lo = 0;
[88d5c1e]1000
1001 counter = count_zeroes64(i);
1002
[c67aff2]1003 exp = FLOAT128_BIAS + 64 - counter - 1;
[88d5c1e]1004
[c67aff2]1005 if (counter == 64) {
[88d5c1e]1006 result.bin.hi = 0;
1007 result.bin.lo = 0;
[c67aff2]1008 return result;
1009 }
[88d5c1e]1010
[c67aff2]1011 frac_hi = 0;
1012 frac_lo = i;
1013 lshift128(frac_hi, frac_lo, (counter + 64 - 1), &frac_hi, &frac_lo);
[88d5c1e]1014
1015 round_float128(&exp, &frac_hi, &frac_lo);
1016
[c67aff2]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;
[88d5c1e]1022
[c67aff2]1023 return result;
1024}
1025
1026float128 int64_to_float128(int64_t i)
1027{
1028 float128 result;
[88d5c1e]1029
1030 if (i < 0)
[c67aff2]1031 result = uint64_to_float128((uint64_t) (-i));
[88d5c1e]1032 else
[c67aff2]1033 result = uint64_to_float128((uint64_t) i);
[88d5c1e]1034
[c67aff2]1035 result.parts.sign = i < 0;
[88d5c1e]1036
1037 return result;
[c67aff2]1038}
1039
[231a60a]1040/** @}
[846848a6]1041 */
Note: See TracBrowser for help on using the repository browser.