1 /*
2  * Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 /*
27  * modf(double x, double *iptr)
28  * return fraction part of x, and return x's integral part in *iptr.
29  * Method:
30  *      Bit twiddling.
31  *
32  * Exception:
33  *      No exception.
34  */
35 
36 #include "fdlibm.h"
37 
38 #ifdef __STDC__
39 static const double one = 1.0;
40 #else
41 static double one = 1.0;
42 #endif
43 
44 #ifdef __STDC__
modf(double x,double * iptr)45         double modf(double x, double *iptr)
46 #else
47         double modf(x, iptr)
48         double x,*iptr;
49 #endif
50 {
51         int i0,i1,j0;
52         unsigned i;
53         i0 =  __HI(x);          /* high x */
54         i1 =  __LO(x);          /* low  x */
55         j0 = ((i0>>20)&0x7ff)-0x3ff;    /* exponent of x */
56         if(j0<20) {                     /* integer part in high x */
57             if(j0<0) {                  /* |x|<1 */
58                 __HIp(iptr) = i0&0x80000000;
59                 __LOp(iptr) = 0;                /* *iptr = +-0 */
60                 return x;
61             } else {
62                 i = (0x000fffff)>>j0;
63                 if(((i0&i)|i1)==0) {            /* x is integral */
64                     *iptr = x;
65                     __HI(x) &= 0x80000000;
66                     __LO(x)  = 0;       /* return +-0 */
67                     return x;
68                 } else {
69                     __HIp(iptr) = i0&(~i);
70                     __LOp(iptr) = 0;
71                     return x - *iptr;
72                 }
73             }
74         } else if (j0>51) {             /* no fraction part */
75             *iptr = x*one;
76             __HI(x) &= 0x80000000;
77             __LO(x)  = 0;       /* return +-0 */
78             return x;
79         } else {                        /* fraction part in low x */
80             i = ((unsigned)(0xffffffff))>>(j0-20);
81             if((i1&i)==0) {             /* x is integral */
82                 *iptr = x;
83                 __HI(x) &= 0x80000000;
84                 __LO(x)  = 0;   /* return +-0 */
85                 return x;
86             } else {
87                 __HIp(iptr) = i0;
88                 __LOp(iptr) = i1&(~i);
89                 return x - *iptr;
90             }
91         }
92 }
93