s_modf.c revision 21673
1178825Sdfr/* @(#)s_modf.c 5.1 93/09/24 */
255682Smarkm/*
355682Smarkm * ====================================================
455682Smarkm * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5178825Sdfr *
655682Smarkm * Developed at SunPro, a Sun Microsystems, Inc. business.
7120945Snectar * Permission to use, copy, modify, and distribute this
8120945Snectar * software is freely granted, provided that this notice
955682Smarkm * is preserved.
1055682Smarkm * ====================================================
1172445Sassar */
1272445Sassar
1372445Sassar#ifndef lint
1455682Smarkmstatic char rcsid[] = "$FreeBSD: head/lib/msun/src/s_modf.c 21673 1997-01-14 07:20:47Z jkh $";
1572445Sassar#endif
1672445Sassar
1772445Sassar/*
18178825Sdfr * modf(double x, double *iptr)
19178825Sdfr * return fraction part of x, and return x's integral part in *iptr.
2055682Smarkm * Method:
2155682Smarkm *	Bit twiddling.
2272445Sassar *
2372445Sassar * Exception:
2472445Sassar *	No exception.
2555682Smarkm */
2672445Sassar
2755682Smarkm#include "math.h"
2872445Sassar#include "math_private.h"
2972445Sassar
3055682Smarkm#ifdef __STDC__
3155682Smarkmstatic const double one = 1.0;
32178825Sdfr#else
3355682Smarkmstatic double one = 1.0;
3455682Smarkm#endif
3572445Sassar
3672445Sassar#ifdef __STDC__
3755682Smarkm	double modf(double x, double *iptr)
3855682Smarkm#else
39102644Snectar	double modf(x, iptr)
4055682Smarkm	double x,*iptr;
4155682Smarkm#endif
42178825Sdfr{
43178825Sdfr	int32_t i0,i1,j0;
44	u_int32_t i;
45	EXTRACT_WORDS(i0,i1,x);
46	j0 = ((i0>>20)&0x7ff)-0x3ff;	/* exponent of x */
47	if(j0<20) {			/* integer part in high x */
48	    if(j0<0) {			/* |x|<1 */
49	        INSERT_WORDS(*iptr,i0&0x80000000,0);	/* *iptr = +-0 */
50		return x;
51	    } else {
52		i = (0x000fffff)>>j0;
53		if(((i0&i)|i1)==0) {		/* x is integral */
54		    u_int32_t high;
55		    *iptr = x;
56		    GET_HIGH_WORD(high,x);
57		    INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
58		    return x;
59		} else {
60		    INSERT_WORDS(*iptr,i0&(~i),0);
61		    return x - *iptr;
62		}
63	    }
64	} else if (j0>51) {		/* no fraction part */
65	    u_int32_t high;
66	    *iptr = x*one;
67	    GET_HIGH_WORD(high,x);
68	    INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
69	    return x;
70	} else {			/* fraction part in low x */
71	    i = ((u_int32_t)(0xffffffff))>>(j0-20);
72	    if((i1&i)==0) { 		/* x is integral */
73	        u_int32_t high;
74		*iptr = x;
75		GET_HIGH_WORD(high,x);
76		INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
77		return x;
78	    } else {
79	        INSERT_WORDS(*iptr,i0,i1&(~i));
80		return x - *iptr;
81	    }
82	}
83}
84