/ base / math / s_modf.c
s_modf.c
 1  #if !defined(__ppc__)
 2  /* @(#)s_modf.c 5.1 93/09/24 */
 3  /*
 4   * ====================================================
 5   * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 6   *
 7   * Developed at SunPro, a Sun Microsystems, Inc. business.
 8   * Permission to use, copy, modify, and distribute this
 9   * software is freely granted, provided that this notice 
10   * is preserved.
11   * ====================================================
12   */
13  
14  #if defined(LIBM_SCCS) && !defined(lint)
15  static char rcsid[] = "$NetBSD: s_modf.c,v 1.8 1995/05/10 20:47:55 jtc Exp $";
16  #endif
17  
18  /*
19   * modf(double x, double *iptr) 
20   * return fraction part of x, and return x's integral part in *iptr.
21   * Method:
22   *	Bit twiddling.
23   *
24   * Exception:
25   *	No exception.
26   */
27  
28  #include "math.h"
29  #include "mathP.h"
30  
31  #ifdef __STDC__
32  static const double one = 1.0;
33  #else
34  static double one = 1.0;
35  #endif
36  
37  #ifdef __STDC__
38  	double modf(double x, double *iptr)
39  #else
40  	double modf(x, iptr)
41  	double x,*iptr;
42  #endif
43  {
44  	int32_t i0,i1,j0;
45  	u_int32_t i;
46  	EXTRACT_WORDS(i0,i1,x);
47  	j0 = ((i0>>20)&0x7ff)-0x3ff;	/* exponent of x */
48  	if(j0<20) {			/* integer part in high x */
49  	    if(j0<0) {			/* |x|<1 */
50  	        INSERT_WORDS(*iptr,i0&0x80000000,0);	/* *iptr = +-0 */
51  		return x;
52  	    } else {
53  		i = (0x000fffff)>>j0;
54  		if(((i0&i)|i1)==0) {		/* x is integral */
55  		    u_int32_t high;
56  		    *iptr = x;
57  		    GET_HIGH_WORD(high,x);
58  		    INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
59  		    return x;
60  		} else {
61  		    INSERT_WORDS(*iptr,i0&(~i),0);
62  		    return x - *iptr;
63  		}
64  	    }
65  	} else if (j0>51) {		/* no fraction part */
66  	    u_int32_t high;
67  	    *iptr = x*one;
68  	    GET_HIGH_WORD(high,x);
69  	    INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
70  	    return x;
71  	} else {			/* fraction part in low x */
72  	    i = ((u_int32_t)(0xffffffff))>>(j0-20);
73  	    if((i1&i)==0) { 		/* x is integral */
74  	        u_int32_t high;
75  		*iptr = x;
76  		GET_HIGH_WORD(high,x);
77  		INSERT_WORDS(x,high&0x80000000,0);	/* return +-0 */
78  		return x;
79  	    } else {
80  	        INSERT_WORDS(*iptr,i0,i1&(~i));
81  		return x - *iptr;
82  	    }
83  	}
84  }
85  #endif /* !__ppc__ */