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