1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/LMATH/S_SCALBN.C Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,106 @@
1.4 +/* S_SCALBN.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_scalbn.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 +<<scalbn>>, <<scalbnf>>---scale by integer
1.26 +INDEX
1.27 + scalbn
1.28 +INDEX
1.29 + scalbnf
1.30 +
1.31 +ANSI_SYNOPSIS
1.32 + #include <math.h>
1.33 + double scalbn(double <[x]>, int <[y]>);
1.34 + float scalbnf(float <[x]>, int <[y]>);
1.35 +
1.36 +TRAD_SYNOPSIS
1.37 + #include <math.h>
1.38 + double scalbn(<[x]>,<[y]>)
1.39 + double <[x]>;
1.40 + int <[y]>;
1.41 + float scalbnf(<[x]>,<[y]>)
1.42 + float <[x]>;
1.43 + int <[y]>;
1.44 +
1.45 +DESCRIPTION
1.46 +<<scalbn>> and <<scalbnf>> scale <[x]> by <[n]>, returning <[x]> times
1.47 +2 to the power <[n]>. The result is computed by manipulating the
1.48 +exponent, rather than by actually performing an exponentiation or
1.49 +multiplication.
1.50 +
1.51 +RETURNS
1.52 +<[x]> times 2 to the power <[n]>.
1.53 +
1.54 +PORTABILITY
1.55 +Neither <<scalbn>> nor <<scalbnf>> is required by ANSI C or by the System V
1.56 +Interface Definition (Issue 2).
1.57 +
1.58 +*/
1.59 +
1.60 +/*
1.61 + * scalbn (double x, int n)
1.62 + * scalbn(x,n) returns x* 2**n computed by exponent
1.63 + * manipulation rather than by actually performing an
1.64 + * exponentiation or a multiplication.
1.65 + */
1.66 +
1.67 +#include "FDLIBM.H"
1.68 +
1.69 +static const double
1.70 +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
1.71 +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
1.72 +huge = 1.0e+300,
1.73 +tiny = 1.0e-300;
1.74 +
1.75 +/**
1.76 +Scales x by n, returning x times
1.77 +2 to the power n. The result is computed by manipulating the
1.78 +exponent, rather than by actually performing an exponentiation or
1.79 +multiplication.
1.80 +@return x times 2 to the power n.
1.81 +@param x floating point value
1.82 +@param n integer power
1.83 +*/
1.84 +EXPORT_C double scalbn (double x, int n) __SOFTFP
1.85 +{
1.86 + __int32_t k,hx,lx;
1.87 + EXTRACT_WORDS(hx,lx,x);
1.88 + k = (hx&0x7ff00000)>>20; /* extract exponent */
1.89 + if (k==0) { /* 0 or subnormal x */
1.90 + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
1.91 + x *= two54;
1.92 + GET_HIGH_WORD(hx,x);
1.93 + k = ((hx&0x7ff00000)>>20) - 54;
1.94 + if (n< -50000) return tiny*x; /*underflow*/
1.95 + }
1.96 + if (k==0x7ff) return x+x; /* NaN or Inf */
1.97 + k = k+n;
1.98 + if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */
1.99 + if (k > 0) /* normal result */
1.100 + {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
1.101 + if (k <= -54) {
1.102 + if (n > 50000) /* in case integer overflow in n+k */
1.103 + return huge*copysign(huge,x); /*overflow*/
1.104 + else return tiny*copysign(tiny,x); /*underflow*/
1.105 + }
1.106 + k += 54; /* subnormal result */
1.107 + SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
1.108 + return x*twom54;
1.109 +}