os/ossrv/genericopenlibs/cstdlib/LMATH/S_FREXP.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /* S_FREXP.C
     2  * 
     3  * Portions Copyright (c) 1993-2005 Nokia Corporation and/or its subsidiary(-ies).
     4  * All rights reserved.
     5  */
     6 
     7 
     8 /* @(#)s_frexp.c 5.1 93/09/24 */
     9 /*
    10  * ====================================================
    11  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
    12  *
    13  * Developed at SunPro, a Sun Microsystems, Inc. business.
    14  * Permission to use, copy, modify, and distribute this
    15  * software is freely granted, provided that this notice 
    16  * is preserved.
    17  * ====================================================
    18  */
    19 
    20 /*
    21 FUNCTION
    22        <<frexp>>, <<frexpf>>---split floating-point number
    23 INDEX
    24 	frexp
    25 INDEX
    26 	frexpf
    27 
    28 ANSI_SYNOPSIS
    29 	#include <math.h>
    30         double frexp(double <[val]>, int *<[exp]>);
    31         float frexpf(float <[val]>, int *<[exp]>);
    32 
    33 TRAD_SYNOPSIS
    34 	#include <math.h>
    35         double frexp(<[val]>, <[exp]>)
    36         double <[val]>;
    37         int *<[exp]>;
    38 
    39         float frexpf(<[val]>, <[exp]>)
    40         float <[val]>;
    41         int *<[exp]>;
    42 
    43 
    44 DESCRIPTION
    45 	All non zero, normal numbers can be described as <[m]> * 2**<[p]>.
    46 	<<frexp>> represents the double <[val]> as a mantissa <[m]>
    47 	and a power of two <[p]>. The resulting mantissa will always
    48 	be greater than or equal to <<0.5>>, and less than <<1.0>> (as
    49 	long as <[val]> is nonzero). The power of two will be stored
    50 	in <<*>><[exp]>. 
    51 
    52 @ifinfo
    53 <[m]> and <[p]> are calculated so that
    54 <[val]> is <[m]> times <<2>> to the power <[p]>.
    55 @end ifinfo
    56 @tex
    57 <[m]> and <[p]> are calculated so that
    58 $ val = m \times 2^p $.
    59 @end tex
    60 
    61 <<frexpf>> is identical, other than taking and returning
    62 floats rather than doubles.
    63 
    64 RETURNS
    65 <<frexp>> returns the mantissa <[m]>. If <[val]> is <<0>>, infinity,
    66 or Nan, <<frexp>> will set <<*>><[exp]> to <<0>> and return <[val]>.
    67 
    68 PORTABILITY
    69 <<frexp>> is ANSI.
    70 <<frexpf>> is an extension.
    71 
    72 
    73 */
    74 
    75 /*
    76  * for non-zero x 
    77  *	x = frexp(arg,&exp);
    78  * return a double fp quantity x such that 0.5 <= |x| <1.0
    79  * and the corresponding binary exponent "exp". That is
    80  *	arg = x*2^exp.
    81  * If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg 
    82  * with *exp=0. 
    83  */
    84 
    85 #include "FDLIBM.H"
    86 
    87 static const double
    88 two54 =  1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
    89 
    90 /**
    91 Get mantissa and exponent of floating-point value.
    92 Calculates mantissa (a floating-point value between 0.5 and 1) 
    93 and exponent (an integer value) where x is parameter x, 
    94 mantissa is the value returned by the function and exponent
    95 is set by the function at location pointed by eptr.
    96 @return Mantissa.
    97 @param x Floating point value 
    98 @param eptr Location where to exponent will be received.
    99 */	
   100 EXPORT_C double frexp(double x, int *eptr) __SOFTFP
   101 {
   102 	__int32_t hx, ix, lx;
   103 	EXTRACT_WORDS(hx,lx,x);
   104 	ix = 0x7fffffff&hx;
   105 	*eptr = 0;
   106 	if(ix>=0x7ff00000||((ix|lx)==0)) return x;	/* 0,inf,nan */
   107 	if (ix<0x00100000) {		/* subnormal */
   108 	    x *= two54;
   109 	    GET_HIGH_WORD(hx,x);
   110 	    ix = hx&0x7fffffff;
   111 	    *eptr = -54;
   112 	}
   113 	*eptr += (ix>>20)-1022;
   114 	hx = (hx&0x800fffff)|0x3fe00000;
   115 	SET_HIGH_WORD(x,hx);
   116 	return x;
   117 }