xref: /minix3/lib/libm/src/s_modf.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
12fe8fb19SBen Gras /* @(#)s_modf.c 5.1 93/09/24 */
22fe8fb19SBen Gras /*
32fe8fb19SBen Gras  * ====================================================
42fe8fb19SBen Gras  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
52fe8fb19SBen Gras  *
62fe8fb19SBen Gras  * Developed at SunPro, a Sun Microsystems, Inc. business.
72fe8fb19SBen Gras  * Permission to use, copy, modify, and distribute this
82fe8fb19SBen Gras  * software is freely granted, provided that this notice
92fe8fb19SBen Gras  * is preserved.
102fe8fb19SBen Gras  * ====================================================
112fe8fb19SBen Gras  */
122fe8fb19SBen Gras 
132fe8fb19SBen Gras #include <sys/cdefs.h>
142fe8fb19SBen Gras #if defined(LIBM_SCCS) && !defined(lint)
15*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: s_modf.c,v 1.15 2014/06/16 12:54:43 joerg Exp $");
162fe8fb19SBen Gras #endif
172fe8fb19SBen Gras 
182fe8fb19SBen Gras /*
192fe8fb19SBen Gras  * modf(double x, double *iptr)
202fe8fb19SBen Gras  * return fraction part of x, and return x's integral part in *iptr.
212fe8fb19SBen Gras  * Method:
222fe8fb19SBen Gras  *	Bit twiddling.
232fe8fb19SBen Gras  *
242fe8fb19SBen Gras  * Exception:
252fe8fb19SBen Gras  *	No exception.
262fe8fb19SBen Gras  */
272fe8fb19SBen Gras 
282fe8fb19SBen Gras #include "math.h"
292fe8fb19SBen Gras #include "math_private.h"
302fe8fb19SBen Gras 
312fe8fb19SBen Gras static const double one = 1.0;
322fe8fb19SBen Gras 
33*0a6a1f1dSLionel Sambuc #ifndef __HAVE_LONG_DOUBLE
__strong_alias(_modfl,modf)34*0a6a1f1dSLionel Sambuc __strong_alias(_modfl, modf)
35*0a6a1f1dSLionel Sambuc __weak_alias(modfl, modf)
36*0a6a1f1dSLionel Sambuc #endif
37*0a6a1f1dSLionel Sambuc 
382fe8fb19SBen Gras double
392fe8fb19SBen Gras modf(double x, double *iptr)
402fe8fb19SBen Gras {
412fe8fb19SBen Gras 	int32_t i0,i1,jj0;
422fe8fb19SBen Gras 	u_int32_t i;
432fe8fb19SBen Gras 	EXTRACT_WORDS(i0,i1,x);
442fe8fb19SBen Gras 	jj0 = (((uint32_t)i0>>20)&0x7ff)-0x3ff;	/* exponent of x */
452fe8fb19SBen Gras 	if(jj0<20) {			/* integer part in high x */
462fe8fb19SBen Gras 	    if(jj0<0) {			/* |x|<1 */
472fe8fb19SBen Gras 	        INSERT_WORDS(*iptr,i0&0x80000000,0);	/* *iptr = +-0 */
482fe8fb19SBen Gras 		return x;
492fe8fb19SBen Gras 	    } else {
502fe8fb19SBen Gras 		i = (0x000fffff)>>jj0;
512fe8fb19SBen Gras 		if(((i0&i)|i1)==0) {		/* x is integral */
522fe8fb19SBen Gras 		    u_int32_t high;
532fe8fb19SBen Gras 		    *iptr = x;
542fe8fb19SBen Gras 		    GET_HIGH_WORD(high,x);
552fe8fb19SBen Gras 		    INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
562fe8fb19SBen Gras 		    return x;
572fe8fb19SBen Gras 		} else {
582fe8fb19SBen Gras 		    INSERT_WORDS(*iptr,i0&(~i),0);
592fe8fb19SBen Gras 		    return x - *iptr;
602fe8fb19SBen Gras 		}
612fe8fb19SBen Gras 	    }
622fe8fb19SBen Gras 	} else if (jj0>51) {		/* no fraction part */
632fe8fb19SBen Gras 	    u_int32_t high;
642fe8fb19SBen Gras 	    *iptr = x*one;
652fe8fb19SBen Gras 	    if (jj0 == 0x400)		/* +-inf or NaN */
662fe8fb19SBen Gras 		return 0.0 / x;		/* +-0 or NaN */
672fe8fb19SBen Gras 	    GET_HIGH_WORD(high,x);
682fe8fb19SBen Gras 	    INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
692fe8fb19SBen Gras 	    return x;
702fe8fb19SBen Gras 	} else {			/* fraction part in low x */
712fe8fb19SBen Gras 	    i = ((u_int32_t)(0xffffffff))>>(jj0-20);
722fe8fb19SBen Gras 	    if((i1&i)==0) { 		/* x is integral */
732fe8fb19SBen Gras 	        u_int32_t high;
742fe8fb19SBen Gras 		*iptr = x;
752fe8fb19SBen Gras 		GET_HIGH_WORD(high,x);
762fe8fb19SBen Gras 		INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
772fe8fb19SBen Gras 		return x;
782fe8fb19SBen Gras 	    } else {
792fe8fb19SBen Gras 	        INSERT_WORDS(*iptr,i0,i1&(~i));
802fe8fb19SBen Gras 		return x - *iptr;
812fe8fb19SBen Gras 	    }
822fe8fb19SBen Gras 	}
832fe8fb19SBen Gras }
84