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