1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
/* @(#)s_modf.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<modf>>, <<modff>>---split fractional and integer parts
INDEX
modf
INDEX
modff
SYNOPSIS
#include <math.h>
double modf(double <[val]>, double *<[ipart]>);
float modff(float <[val]>, float *<[ipart]>);
DESCRIPTION
<<modf>> splits the double <[val]> apart into an integer part
and a fractional part, returning the fractional part and
storing the integer part in <<*<[ipart]>>>. No rounding
whatsoever is done; the sum of the integer and fractional
parts is guaranteed to be exactly equal to <[val]>. That
is, if <[realpart]> = modf(<[val]>, &<[intpart]>); then
`<<<[realpart]>+<[intpart]>>>' is the same as <[val]>.
<<modff>> is identical, save that it takes and returns
<<float>> rather than <<double>> values.
RETURNS
The fractional part is returned. Each result has the same
sign as the supplied argument <[val]>.
PORTABILITY
<<modf>> is ANSI C. <<modff>> is an extension.
QUICKREF
modf ansi pure
modff - pure
*/
/*
* modf(double x, double *iptr)
* return fraction part of x, and return x's integral part in *iptr.
* Method:
* Bit twiddling.
*
* Exception:
* No exception.
*/
#include "fdlibm.h"
#ifdef _NEED_FLOAT64
__float64
modf64(__float64 x, __float64 *iptr)
{
__int32_t i0,i1,j0;
__uint32_t i;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
if(j0<20) { /* integer part in high x */
if(j0<0) { /* |x|<1 */
INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
return x;
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) { /* x is integral */
*iptr = x;
INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
return x;
} else {
INSERT_WORDS(*iptr,i0&(~i),0);
return x - *iptr;
}
}
} else if (j0>51) { /* no fraction part */
*iptr = x;
if (__fpclassifyd(x) == FP_NAN) return *iptr = x+x; /* x is NaN, return NaN */
INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
return x;
} else { /* fraction part in low x */
i = ((__uint32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) { /* x is integral */
*iptr = x;
INSERT_WORDS(x,i0&0x80000000,0); /* return +-0 */
return x;
} else {
INSERT_WORDS(*iptr,i0,i1&(~i));
return x - *iptr;
}
}
}
_MATH_ALIAS_d_dD(modf)
#endif /* _NEED_FLOAT64 */
|