| 1 | /* |
|---|
| 2 | * ==================================================== |
|---|
| 3 | * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
|---|
| 4 | * |
|---|
| 5 | * Developed at SunPro, a Sun Microsystems, Inc. business. |
|---|
| 6 | * Permission to use, copy, modify, and distribute this |
|---|
| 7 | * software is freely granted, provided that this notice |
|---|
| 8 | * is preserved. |
|---|
| 9 | * ==================================================== |
|---|
| 10 | */ |
|---|
| 11 | /* |
|---|
| 12 | FUNCTION |
|---|
| 13 | <<round>>, <<roundf>>---round to integer, to nearest |
|---|
| 14 | INDEX |
|---|
| 15 | round |
|---|
| 16 | INDEX |
|---|
| 17 | roundf |
|---|
| 18 | |
|---|
| 19 | SYNOPSIS |
|---|
| 20 | #include <math.h> |
|---|
| 21 | double round(double <[x]>); |
|---|
| 22 | float roundf(float <[x]>); |
|---|
| 23 | |
|---|
| 24 | DESCRIPTION |
|---|
| 25 | The <<round>> functions round their argument to the nearest integer |
|---|
| 26 | value in floating-point format, rounding halfway cases away from zero, |
|---|
| 27 | regardless of the current rounding direction. (While the "inexact" |
|---|
| 28 | floating-point exception behavior is unspecified by the C standard, the |
|---|
| 29 | <<round>> functions are written so that "inexact" is not raised if the |
|---|
| 30 | result does not equal the argument, which behavior is as recommended by |
|---|
| 31 | IEEE 754 for its related functions.) |
|---|
| 32 | |
|---|
| 33 | RETURNS |
|---|
| 34 | <[x]> rounded to an integral value. |
|---|
| 35 | |
|---|
| 36 | PORTABILITY |
|---|
| 37 | ANSI C, POSIX |
|---|
| 38 | |
|---|
| 39 | SEEALSO |
|---|
| 40 | <<nearbyint>>, <<rint>> |
|---|
| 41 | |
|---|
| 42 | */ |
|---|
| 43 | |
|---|
| 44 | #include "fdlibm.h" |
|---|
| 45 | |
|---|
| 46 | #ifndef _DOUBLE_IS_32BITS |
|---|
| 47 | |
|---|
| 48 | #ifdef __STDC__ |
|---|
| 49 | double round(double x) |
|---|
| 50 | #else |
|---|
| 51 | double round(x) |
|---|
| 52 | double x; |
|---|
| 53 | #endif |
|---|
| 54 | { |
|---|
| 55 | /* Most significant word, least significant word. */ |
|---|
| 56 | __int32_t msw, exponent_less_1023; |
|---|
| 57 | __uint32_t lsw; |
|---|
| 58 | |
|---|
| 59 | EXTRACT_WORDS(msw, lsw, x); |
|---|
| 60 | |
|---|
| 61 | /* Extract exponent field. */ |
|---|
| 62 | exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023; |
|---|
| 63 | |
|---|
| 64 | if (exponent_less_1023 < 20) |
|---|
| 65 | { |
|---|
| 66 | if (exponent_less_1023 < 0) |
|---|
| 67 | { |
|---|
| 68 | msw &= 0x80000000; |
|---|
| 69 | if (exponent_less_1023 == -1) |
|---|
| 70 | /* Result is +1.0 or -1.0. */ |
|---|
| 71 | msw |= (1023 << 20); |
|---|
| 72 | lsw = 0; |
|---|
| 73 | } |
|---|
| 74 | else |
|---|
| 75 | { |
|---|
| 76 | __uint32_t exponent_mask = 0x000fffff >> exponent_less_1023; |
|---|
| 77 | if ((msw & exponent_mask) == 0 && lsw == 0) |
|---|
| 78 | /* x in an integral value. */ |
|---|
| 79 | return x; |
|---|
| 80 | |
|---|
| 81 | msw += 0x00080000 >> exponent_less_1023; |
|---|
| 82 | msw &= ~exponent_mask; |
|---|
| 83 | lsw = 0; |
|---|
| 84 | } |
|---|
| 85 | } |
|---|
| 86 | else if (exponent_less_1023 > 51) |
|---|
| 87 | { |
|---|
| 88 | if (exponent_less_1023 == 1024) |
|---|
| 89 | /* x is NaN or infinite. */ |
|---|
| 90 | return x + x; |
|---|
| 91 | else |
|---|
| 92 | return x; |
|---|
| 93 | } |
|---|
| 94 | else |
|---|
| 95 | { |
|---|
| 96 | __uint32_t exponent_mask = 0xffffffff >> (exponent_less_1023 - 20); |
|---|
| 97 | __uint32_t tmp; |
|---|
| 98 | |
|---|
| 99 | if ((lsw & exponent_mask) == 0) |
|---|
| 100 | /* x is an integral value. */ |
|---|
| 101 | return x; |
|---|
| 102 | |
|---|
| 103 | tmp = lsw + (1 << (51 - exponent_less_1023)); |
|---|
| 104 | if (tmp < lsw) |
|---|
| 105 | msw += 1; |
|---|
| 106 | lsw = tmp; |
|---|
| 107 | |
|---|
| 108 | lsw &= ~exponent_mask; |
|---|
| 109 | } |
|---|
| 110 | INSERT_WORDS(x, msw, lsw); |
|---|
| 111 | |
|---|
| 112 | return x; |
|---|
| 113 | } |
|---|
| 114 | |
|---|
| 115 | #endif /* _DOUBLE_IS_32BITS */ |
|---|