sl@0: /* S_MODF.C sl@0: * sl@0: * Portions Copyright (c) 1993-1999 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: */ sl@0: sl@0: sl@0: /* @(#)s_modf.c 5.1 93/09/24 */ sl@0: /* sl@0: * ==================================================== sl@0: * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. sl@0: * sl@0: * Developed at SunPro, a Sun Microsystems, Inc. business. sl@0: * Permission to use, copy, modify, and distribute this sl@0: * software is freely granted, provided that this notice sl@0: * is preserved. sl@0: * ==================================================== sl@0: */ sl@0: sl@0: /* sl@0: FUNCTION sl@0: <>, <>---split fractional and integer parts sl@0: sl@0: INDEX sl@0: modf sl@0: INDEX sl@0: modff sl@0: sl@0: ANSI_SYNOPSIS sl@0: #include sl@0: double modf(double <[val]>, double *<[ipart]>); sl@0: float modff(float <[val]>, float *<[ipart]>); sl@0: sl@0: TRAD_SYNOPSIS sl@0: #include sl@0: double modf(<[val]>, <[ipart]>) sl@0: double <[val]>; sl@0: double *<[ipart]>; sl@0: sl@0: float modff(<[val]>, <[ipart]>) sl@0: float <[val]>; sl@0: float *<[ipart]>; sl@0: sl@0: DESCRIPTION sl@0: <> splits the double <[val]> apart into an integer part sl@0: and a fractional part, returning the fractional part and sl@0: storing the integer part in <<*<[ipart]>>>. No rounding sl@0: whatsoever is done; the sum of the integer and fractional sl@0: parts is guaranteed to be exactly equal to <[val]>. That sl@0: is, if . <[realpart]> = modf(<[val]>, &<[intpart]>); then sl@0: `<<<[realpart]>+<[intpart]>>>' is the same as <[val]>. sl@0: <> is identical, save that it takes and returns sl@0: <> rather than <> values. sl@0: sl@0: RETURNS sl@0: The fractional part is returned. Each result has the same sl@0: sign as the supplied argument <[val]>. sl@0: sl@0: PORTABILITY sl@0: <> is ANSI C. <> is an extension. sl@0: sl@0: QUICKREF sl@0: modf ansi pure sl@0: modff - pure sl@0: sl@0: */ sl@0: sl@0: /* sl@0: * modf(double x, double *iptr) sl@0: * return fraction part of x, and return x's integral part in *iptr. sl@0: * Method: sl@0: * Bit twiddling. sl@0: * sl@0: * Exception: sl@0: * No exception. sl@0: */ sl@0: sl@0: #include "FDLIBM.H" sl@0: sl@0: static const double one = 1.0; sl@0: sl@0: /** sl@0: Split floating-point value into fractional and integer parts. sl@0: Breaks x in two parts: the integer (stored in location pointed by iptr) sl@0: and the fraction (return value). sl@0: @return Fractional part of x sl@0: @param x Floating point value. sl@0: @param iptr Location where the integer part of x will be stored. sl@0: */ sl@0: EXPORT_C double modf(double x, double *iptr) __SOFTFP sl@0: { sl@0: __int32_t i0,i1,j0; sl@0: __uint32_t i; sl@0: EXTRACT_WORDS(i0,i1,x); sl@0: j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ sl@0: if(j0<20) { /* integer part in high x */ sl@0: if(j0<0) { /* |x|<1 */ sl@0: INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ sl@0: return x; sl@0: } else { sl@0: i = (0x000fffff)>>j0; sl@0: if(((i0&i)|i1)==0) { /* x is integral */ sl@0: __uint32_t high; sl@0: *iptr = x; sl@0: GET_HIGH_WORD(high,x); sl@0: INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ sl@0: return x; sl@0: } else { sl@0: INSERT_WORDS(*iptr,i0&(~i),0); sl@0: return x - *iptr; sl@0: } sl@0: } sl@0: } else if (j0>51) { /* no fraction part */ sl@0: __uint32_t high; sl@0: *iptr = x*one; sl@0: GET_HIGH_WORD(high,x); sl@0: INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ sl@0: return x; sl@0: } else { /* fraction part in low x */ sl@0: i = ((__uint32_t)(0xffffffff))>>(j0-20); sl@0: if((i1&i)==0) { /* x is integral */ sl@0: __uint32_t high; sl@0: *iptr = x; sl@0: GET_HIGH_WORD(high,x); sl@0: INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ sl@0: return x; sl@0: } else { sl@0: INSERT_WORDS(*iptr,i0,i1&(~i)); sl@0: return x - *iptr; sl@0: } sl@0: } sl@0: }