diff options
Diffstat (limited to 'REORG.TODO/sysdeps/ieee754/dbl-64/s_modf.c')
-rw-r--r-- | REORG.TODO/sysdeps/ieee754/dbl-64/s_modf.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/REORG.TODO/sysdeps/ieee754/dbl-64/s_modf.c b/REORG.TODO/sysdeps/ieee754/dbl-64/s_modf.c new file mode 100644 index 0000000000..0a1e13008f --- /dev/null +++ b/REORG.TODO/sysdeps/ieee754/dbl-64/s_modf.c @@ -0,0 +1,86 @@ +/* + * ==================================================== + * 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. + * ==================================================== + */ + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include <math.h> +#include <math_private.h> + +static const double one = 1.0; + +double +__modf (double x, double *iptr) +{ + int32_t i0, i1, j0; + u_int32_t i; + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ + if (j0 < 20) /* integer part in high x */ + { + if (j0 < 0) /* |x|<1 */ + { + INSERT_WORDS (*iptr, i0 & 0x80000000, 0); /* *iptr = +-0 */ + return x; + } + else + { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) /* x is integral */ + { + *iptr = x; + INSERT_WORDS (x, i0 & 0x80000000, 0); /* return +-0 */ + return x; + } + else + { + INSERT_WORDS (*iptr, i0 & (~i), 0); + return x - *iptr; + } + } + } + else if (__glibc_unlikely (j0 > 51)) /* no fraction part */ + { + *iptr = x * one; + /* We must handle NaNs separately. */ + if (j0 == 0x400 && ((i0 & 0xfffff) | i1)) + return x * one; + INSERT_WORDS (x, i0 & 0x80000000, 0); /* return +-0 */ + return x; + } + else /* fraction part in low x */ + { + i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) /* x is integral */ + { + *iptr = x; + INSERT_WORDS (x, i0 & 0x80000000, 0); /* return +-0 */ + return x; + } + else + { + INSERT_WORDS (*iptr, i0, i1 & (~i)); + return x - *iptr; + } + } +} +weak_alias (__modf, modf) +#ifdef NO_LONG_DOUBLE +strong_alias (__modf, __modfl) +weak_alias (__modf, modfl) +#endif |