os/ossrv/genericopenlibs/cstdlib/LMATH/S_FREXP.C
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/LMATH/S_FREXP.C	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,117 @@
     1.4 +/* S_FREXP.C
     1.5 + * 
     1.6 + * Portions Copyright (c) 1993-2005 Nokia Corporation and/or its subsidiary(-ies).
     1.7 + * All rights reserved.
     1.8 + */
     1.9 +
    1.10 +
    1.11 +/* @(#)s_frexp.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 +       <<frexp>>, <<frexpf>>---split floating-point number
    1.26 +INDEX
    1.27 +	frexp
    1.28 +INDEX
    1.29 +	frexpf
    1.30 +
    1.31 +ANSI_SYNOPSIS
    1.32 +	#include <math.h>
    1.33 +        double frexp(double <[val]>, int *<[exp]>);
    1.34 +        float frexpf(float <[val]>, int *<[exp]>);
    1.35 +
    1.36 +TRAD_SYNOPSIS
    1.37 +	#include <math.h>
    1.38 +        double frexp(<[val]>, <[exp]>)
    1.39 +        double <[val]>;
    1.40 +        int *<[exp]>;
    1.41 +
    1.42 +        float frexpf(<[val]>, <[exp]>)
    1.43 +        float <[val]>;
    1.44 +        int *<[exp]>;
    1.45 +
    1.46 +
    1.47 +DESCRIPTION
    1.48 +	All non zero, normal numbers can be described as <[m]> * 2**<[p]>.
    1.49 +	<<frexp>> represents the double <[val]> as a mantissa <[m]>
    1.50 +	and a power of two <[p]>. The resulting mantissa will always
    1.51 +	be greater than or equal to <<0.5>>, and less than <<1.0>> (as
    1.52 +	long as <[val]> is nonzero). The power of two will be stored
    1.53 +	in <<*>><[exp]>. 
    1.54 +
    1.55 +@ifinfo
    1.56 +<[m]> and <[p]> are calculated so that
    1.57 +<[val]> is <[m]> times <<2>> to the power <[p]>.
    1.58 +@end ifinfo
    1.59 +@tex
    1.60 +<[m]> and <[p]> are calculated so that
    1.61 +$ val = m \times 2^p $.
    1.62 +@end tex
    1.63 +
    1.64 +<<frexpf>> is identical, other than taking and returning
    1.65 +floats rather than doubles.
    1.66 +
    1.67 +RETURNS
    1.68 +<<frexp>> returns the mantissa <[m]>. If <[val]> is <<0>>, infinity,
    1.69 +or Nan, <<frexp>> will set <<*>><[exp]> to <<0>> and return <[val]>.
    1.70 +
    1.71 +PORTABILITY
    1.72 +<<frexp>> is ANSI.
    1.73 +<<frexpf>> is an extension.
    1.74 +
    1.75 +
    1.76 +*/
    1.77 +
    1.78 +/*
    1.79 + * for non-zero x 
    1.80 + *	x = frexp(arg,&exp);
    1.81 + * return a double fp quantity x such that 0.5 <= |x| <1.0
    1.82 + * and the corresponding binary exponent "exp". That is
    1.83 + *	arg = x*2^exp.
    1.84 + * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg 
    1.85 + * with *exp=0. 
    1.86 + */
    1.87 +
    1.88 +#include "FDLIBM.H"
    1.89 +
    1.90 +static const double
    1.91 +two54 =  1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
    1.92 +
    1.93 +/**
    1.94 +Get mantissa and exponent of floating-point value.
    1.95 +Calculates mantissa (a floating-point value between 0.5 and 1) 
    1.96 +and exponent (an integer value) where x is parameter x, 
    1.97 +mantissa is the value returned by the function and exponent
    1.98 +is set by the function at location pointed by eptr.
    1.99 +@return Mantissa.
   1.100 +@param x Floating point value 
   1.101 +@param eptr Location where to exponent will be received.
   1.102 +*/	
   1.103 +EXPORT_C double frexp(double x, int *eptr) __SOFTFP
   1.104 +{
   1.105 +	__int32_t hx, ix, lx;
   1.106 +	EXTRACT_WORDS(hx,lx,x);
   1.107 +	ix = 0x7fffffff&hx;
   1.108 +	*eptr = 0;
   1.109 +	if(ix>=0x7ff00000||((ix|lx)==0)) return x;	/* 0,inf,nan */
   1.110 +	if (ix<0x00100000) {		/* subnormal */
   1.111 +	    x *= two54;
   1.112 +	    GET_HIGH_WORD(hx,x);
   1.113 +	    ix = hx&0x7fffffff;
   1.114 +	    *eptr = -54;
   1.115 +	}
   1.116 +	*eptr += (ix>>20)-1022;
   1.117 +	hx = (hx&0x800fffff)|0x3fe00000;
   1.118 +	SET_HIGH_WORD(x,hx);
   1.119 +	return x;
   1.120 +}