|
1 /* S_MODF.C |
|
2 * |
|
3 * Portions Copyright (c) 1993-1999 Nokia Corporation and/or its subsidiary(-ies). |
|
4 * All rights reserved. |
|
5 */ |
|
6 |
|
7 |
|
8 /* @(#)s_modf.c 5.1 93/09/24 */ |
|
9 /* |
|
10 * ==================================================== |
|
11 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
|
12 * |
|
13 * Developed at SunPro, a Sun Microsystems, Inc. business. |
|
14 * Permission to use, copy, modify, and distribute this |
|
15 * software is freely granted, provided that this notice |
|
16 * is preserved. |
|
17 * ==================================================== |
|
18 */ |
|
19 |
|
20 /* |
|
21 FUNCTION |
|
22 <<modf>>, <<modff>>---split fractional and integer parts |
|
23 |
|
24 INDEX |
|
25 modf |
|
26 INDEX |
|
27 modff |
|
28 |
|
29 ANSI_SYNOPSIS |
|
30 #include <math.h> |
|
31 double modf(double <[val]>, double *<[ipart]>); |
|
32 float modff(float <[val]>, float *<[ipart]>); |
|
33 |
|
34 TRAD_SYNOPSIS |
|
35 #include <math.h> |
|
36 double modf(<[val]>, <[ipart]>) |
|
37 double <[val]>; |
|
38 double *<[ipart]>; |
|
39 |
|
40 float modff(<[val]>, <[ipart]>) |
|
41 float <[val]>; |
|
42 float *<[ipart]>; |
|
43 |
|
44 DESCRIPTION |
|
45 <<modf>> splits the double <[val]> apart into an integer part |
|
46 and a fractional part, returning the fractional part and |
|
47 storing the integer part in <<*<[ipart]>>>. No rounding |
|
48 whatsoever is done; the sum of the integer and fractional |
|
49 parts is guaranteed to be exactly equal to <[val]>. That |
|
50 is, if . <[realpart]> = modf(<[val]>, &<[intpart]>); then |
|
51 `<<<[realpart]>+<[intpart]>>>' is the same as <[val]>. |
|
52 <<modff>> is identical, save that it takes and returns |
|
53 <<float>> rather than <<double>> values. |
|
54 |
|
55 RETURNS |
|
56 The fractional part is returned. Each result has the same |
|
57 sign as the supplied argument <[val]>. |
|
58 |
|
59 PORTABILITY |
|
60 <<modf>> is ANSI C. <<modff>> is an extension. |
|
61 |
|
62 QUICKREF |
|
63 modf ansi pure |
|
64 modff - pure |
|
65 |
|
66 */ |
|
67 |
|
68 /* |
|
69 * modf(double x, double *iptr) |
|
70 * return fraction part of x, and return x's integral part in *iptr. |
|
71 * Method: |
|
72 * Bit twiddling. |
|
73 * |
|
74 * Exception: |
|
75 * No exception. |
|
76 */ |
|
77 |
|
78 #include "FDLIBM.H" |
|
79 |
|
80 static const double one = 1.0; |
|
81 |
|
82 /** |
|
83 Split floating-point value into fractional and integer parts. |
|
84 Breaks x in two parts: the integer (stored in location pointed by iptr) |
|
85 and the fraction (return value). |
|
86 @return Fractional part of x |
|
87 @param x Floating point value. |
|
88 @param iptr Location where the integer part of x will be stored. |
|
89 */ |
|
90 EXPORT_C double modf(double x, double *iptr) __SOFTFP |
|
91 { |
|
92 __int32_t i0,i1,j0; |
|
93 __uint32_t i; |
|
94 EXTRACT_WORDS(i0,i1,x); |
|
95 j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ |
|
96 if(j0<20) { /* integer part in high x */ |
|
97 if(j0<0) { /* |x|<1 */ |
|
98 INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ |
|
99 return x; |
|
100 } else { |
|
101 i = (0x000fffff)>>j0; |
|
102 if(((i0&i)|i1)==0) { /* x is integral */ |
|
103 __uint32_t high; |
|
104 *iptr = x; |
|
105 GET_HIGH_WORD(high,x); |
|
106 INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ |
|
107 return x; |
|
108 } else { |
|
109 INSERT_WORDS(*iptr,i0&(~i),0); |
|
110 return x - *iptr; |
|
111 } |
|
112 } |
|
113 } else if (j0>51) { /* no fraction part */ |
|
114 __uint32_t high; |
|
115 *iptr = x*one; |
|
116 GET_HIGH_WORD(high,x); |
|
117 INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ |
|
118 return x; |
|
119 } else { /* fraction part in low x */ |
|
120 i = ((__uint32_t)(0xffffffff))>>(j0-20); |
|
121 if((i1&i)==0) { /* x is integral */ |
|
122 __uint32_t high; |
|
123 *iptr = x; |
|
124 GET_HIGH_WORD(high,x); |
|
125 INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ |
|
126 return x; |
|
127 } else { |
|
128 INSERT_WORDS(*iptr,i0,i1&(~i)); |
|
129 return x - *iptr; |
|
130 } |
|
131 } |
|
132 } |