1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/LMATH/S_MODF.C Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,132 @@
1.4 +/* S_MODF.C
1.5 + *
1.6 + * Portions Copyright (c) 1993-1999 Nokia Corporation and/or its subsidiary(-ies).
1.7 + * All rights reserved.
1.8 + */
1.9 +
1.10 +
1.11 +/* @(#)s_modf.c 5.1 93/09/24 */
1.12 +/*
1.13 + * ====================================================
1.14 + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
1.15 + *
1.16 + * Developed at SunPro, a Sun Microsystems, Inc. business.
1.17 + * Permission to use, copy, modify, and distribute this
1.18 + * software is freely granted, provided that this notice
1.19 + * is preserved.
1.20 + * ====================================================
1.21 + */
1.22 +
1.23 +/*
1.24 +FUNCTION
1.25 + <<modf>>, <<modff>>---split fractional and integer parts
1.26 +
1.27 +INDEX
1.28 + modf
1.29 +INDEX
1.30 + modff
1.31 +
1.32 +ANSI_SYNOPSIS
1.33 + #include <math.h>
1.34 + double modf(double <[val]>, double *<[ipart]>);
1.35 + float modff(float <[val]>, float *<[ipart]>);
1.36 +
1.37 +TRAD_SYNOPSIS
1.38 + #include <math.h>
1.39 + double modf(<[val]>, <[ipart]>)
1.40 + double <[val]>;
1.41 + double *<[ipart]>;
1.42 +
1.43 + float modff(<[val]>, <[ipart]>)
1.44 + float <[val]>;
1.45 + float *<[ipart]>;
1.46 +
1.47 +DESCRIPTION
1.48 + <<modf>> splits the double <[val]> apart into an integer part
1.49 + and a fractional part, returning the fractional part and
1.50 + storing the integer part in <<*<[ipart]>>>. No rounding
1.51 + whatsoever is done; the sum of the integer and fractional
1.52 + parts is guaranteed to be exactly equal to <[val]>. That
1.53 + is, if . <[realpart]> = modf(<[val]>, &<[intpart]>); then
1.54 + `<<<[realpart]>+<[intpart]>>>' is the same as <[val]>.
1.55 + <<modff>> is identical, save that it takes and returns
1.56 + <<float>> rather than <<double>> values.
1.57 +
1.58 +RETURNS
1.59 + The fractional part is returned. Each result has the same
1.60 + sign as the supplied argument <[val]>.
1.61 +
1.62 +PORTABILITY
1.63 + <<modf>> is ANSI C. <<modff>> is an extension.
1.64 +
1.65 +QUICKREF
1.66 + modf ansi pure
1.67 + modff - pure
1.68 +
1.69 +*/
1.70 +
1.71 +/*
1.72 + * modf(double x, double *iptr)
1.73 + * return fraction part of x, and return x's integral part in *iptr.
1.74 + * Method:
1.75 + * Bit twiddling.
1.76 + *
1.77 + * Exception:
1.78 + * No exception.
1.79 + */
1.80 +
1.81 +#include "FDLIBM.H"
1.82 +
1.83 +static const double one = 1.0;
1.84 +
1.85 +/**
1.86 +Split floating-point value into fractional and integer parts.
1.87 +Breaks x in two parts: the integer (stored in location pointed by iptr)
1.88 +and the fraction (return value).
1.89 +@return Fractional part of x
1.90 +@param x Floating point value.
1.91 +@param iptr Location where the integer part of x will be stored.
1.92 +*/
1.93 +EXPORT_C double modf(double x, double *iptr) __SOFTFP
1.94 +{
1.95 + __int32_t i0,i1,j0;
1.96 + __uint32_t i;
1.97 + EXTRACT_WORDS(i0,i1,x);
1.98 + j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */
1.99 + if(j0<20) { /* integer part in high x */
1.100 + if(j0<0) { /* |x|<1 */
1.101 + INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */
1.102 + return x;
1.103 + } else {
1.104 + i = (0x000fffff)>>j0;
1.105 + if(((i0&i)|i1)==0) { /* x is integral */
1.106 + __uint32_t high;
1.107 + *iptr = x;
1.108 + GET_HIGH_WORD(high,x);
1.109 + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
1.110 + return x;
1.111 + } else {
1.112 + INSERT_WORDS(*iptr,i0&(~i),0);
1.113 + return x - *iptr;
1.114 + }
1.115 + }
1.116 + } else if (j0>51) { /* no fraction part */
1.117 + __uint32_t high;
1.118 + *iptr = x*one;
1.119 + GET_HIGH_WORD(high,x);
1.120 + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
1.121 + return x;
1.122 + } else { /* fraction part in low x */
1.123 + i = ((__uint32_t)(0xffffffff))>>(j0-20);
1.124 + if((i1&i)==0) { /* x is integral */
1.125 + __uint32_t high;
1.126 + *iptr = x;
1.127 + GET_HIGH_WORD(high,x);
1.128 + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */
1.129 + return x;
1.130 + } else {
1.131 + INSERT_WORDS(*iptr,i0,i1&(~i));
1.132 + return x - *iptr;
1.133 + }
1.134 + }
1.135 +}