0,0 → 1,115 |
/* |
* ==================================================== |
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
* |
* Developed at SunPro, a Sun Microsystems, Inc. business. |
* Permission to use, copy, modify, and distribute this |
* software is freely granted, provided that this notice |
* is preserved. |
* ==================================================== |
*/ |
/* |
FUNCTION |
<<round>>, <<roundf>>--round to integer, to nearest |
INDEX |
round |
INDEX |
roundf |
|
ANSI_SYNOPSIS |
#include <math.h> |
double round(double <[x]>); |
float roundf(float <[x]>); |
|
DESCRIPTION |
The <<round>> functions round their argument to the nearest integer |
value in floating-point format, rounding halfway cases away from zero, |
regardless of the current rounding direction. (While the "inexact" |
floating-point exception behavior is unspecified by the C standard, the |
<<round>> functions are written so that "inexact" is not raised if the |
result does not equal the argument, which behavior is as recommended by |
IEEE 754 for its related functions.) |
|
RETURNS |
<[x]> rounded to an integral value. |
|
PORTABILITY |
ANSI C, POSIX |
|
SEEALSO |
<<nearbyint>>, <<rint>> |
|
*/ |
|
#include "fdlibm.h" |
|
#ifndef _DOUBLE_IS_32BITS |
|
#ifdef __STDC__ |
double round(double x) |
#else |
double round(x) |
double x; |
#endif |
{ |
/* Most significant word, least significant word. */ |
__int32_t msw, exponent_less_1023; |
__uint32_t lsw; |
|
EXTRACT_WORDS(msw, lsw, x); |
|
/* Extract exponent field. */ |
exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023; |
|
if (exponent_less_1023 < 20) |
{ |
if (exponent_less_1023 < 0) |
{ |
msw &= 0x80000000; |
if (exponent_less_1023 == -1) |
/* Result is +1.0 or -1.0. */ |
msw |= (1023 << 20); |
lsw = 0; |
} |
else |
{ |
__uint32_t exponent_mask = 0x000fffff >> exponent_less_1023; |
if ((msw & exponent_mask) == 0 && lsw == 0) |
/* x in an integral value. */ |
return x; |
|
msw += 0x00080000 >> exponent_less_1023; |
msw &= ~exponent_mask; |
lsw = 0; |
} |
} |
else if (exponent_less_1023 > 51) |
{ |
if (exponent_less_1023 == 1024) |
/* x is NaN or infinite. */ |
return x + x; |
else |
return x; |
} |
else |
{ |
__uint32_t exponent_mask = 0xffffffff >> (exponent_less_1023 - 20); |
__uint32_t tmp; |
|
if ((lsw & exponent_mask) == 0) |
/* x is an integral value. */ |
return x; |
|
tmp = lsw + (1 << (51 - exponent_less_1023)); |
if (tmp < lsw) |
msw += 1; |
lsw = tmp; |
|
lsw &= ~exponent_mask; |
} |
INSERT_WORDS(x, msw, lsw); |
|
return x; |
} |
|
#endif /* _DOUBLE_IS_32BITS */ |