1/* s_modfl.c -- long double version of s_modf.c. 2 * Conversion to long double by Ulrich Drepper, 3 * Cygnus Support, drepper@cygnus.com. 4 */ 5 6/* 7 * ==================================================== 8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 9 * 10 * Developed at SunPro, a Sun Microsystems, Inc. business. 11 * Permission to use, copy, modify, and distribute this 12 * software is freely granted, provided that this notice 13 * is preserved. 14 * ==================================================== 15 */ 16 17#if defined(LIBM_SCCS) && !defined(lint) 18static char rcsid[] = "$NetBSD: $"; 19#endif 20 21/* 22 * modfl(long double x, long double *iptr) 23 * return fraction part of x, and return x's integral part in *iptr. 24 * Method: 25 * Bit twiddling. 26 * 27 * Exception: 28 * No exception. 29 */ 30 31#include "math.h" 32#include "math_private.h" 33 34#ifdef __STDC__ 35static const long double one = 1.0; 36#else 37static long double one = 1.0; 38#endif 39 40#ifdef __STDC__ 41 long double __modfl(long double x, long double *iptr) 42#else 43 long double __modfl(x, iptr) 44 long double x,*iptr; 45#endif 46{ 47 int32_t i0, i1, j0; 48 u_int32_t i, se; 49 GET_LDOUBLE_WORDS(se,i0,i1,x); 50 j0 = (se & 0x7fff) - 0x3fff; /* exponent of x */ 51 if (j0 < 32) { /* integer part in high x */ 52 if (j0 < 0) { /* |x|<1 */ 53 SET_LDOUBLE_WORDS(*iptr,se&0x8000,0,0); /* *iptr = +-0 */ 54 return x; 55 } else { 56 i = (0x7fffffff) >> j0; 57 if (((i0 & i) | i1) == 0) { /* x is integral */ 58 *iptr = x; 59 SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ 60 return x; 61 } else { 62 SET_LDOUBLE_WORDS(*iptr,se,i0&(~i),0); 63 return x - *iptr; 64 } 65 } 66 } else if (j0 > 63) { /* no fraction part */ 67 *iptr = x * one; 68 /* We must handle NaNs separately. */ 69 if (j0 == 0x4000 && ((i0 & 0x7fffffff) | i1)) 70 return x * one; 71 SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ 72 return x; 73 } else { /* fraction part in low x */ 74 i = ((u_int32_t) (0x7fffffff)) >> (j0 - 32); 75 if ((i1 & i) == 0) { /* x is integral */ 76 *iptr = x; 77 SET_LDOUBLE_WORDS(x,se&0x8000,0,0); /* return +-0 */ 78 return x; 79 } else { 80 SET_LDOUBLE_WORDS(*iptr,se,i0,i1&(~i)); 81 return x - *iptr; 82 } 83 } 84} 85weak_alias (__modfl, modfl) 86 87