You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
1.8 KiB
63 lines
1.8 KiB
|
|
/* @(#)s_scalbn.c 1.3 95/01/18 */ |
|
/* |
|
* ==================================================== |
|
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. |
|
* |
|
* Developed at SunSoft, a Sun Microsystems, Inc. business. |
|
* Permission to use, copy, modify, and distribute this |
|
* software is freely granted, provided that this notice |
|
* is preserved. |
|
* ==================================================== |
|
*/ |
|
|
|
/* |
|
* ieee_scalbn (double x, int n) |
|
* ieee_scalbn(x,n) returns x* 2**n computed by exponent |
|
* manipulation rather than by actually performing an |
|
* exponentiation or a multiplication. |
|
*/ |
|
|
|
#include "fdlibm.h" |
|
|
|
#ifdef __STDC__ |
|
static const double |
|
#else |
|
static double |
|
#endif |
|
two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ |
|
twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ |
|
huge = 1.0e+300, |
|
tiny = 1.0e-300; |
|
|
|
#ifdef __STDC__ |
|
double ieee_scalbn (double x, int n) |
|
#else |
|
double ieee_scalbn (x,n) |
|
double x; int n; |
|
#endif |
|
{ |
|
int k,hx,lx; |
|
hx = __HI(x); |
|
lx = __LO(x); |
|
k = (hx&0x7ff00000)>>20; /* extract exponent */ |
|
if (k==0) { /* 0 or subnormal x */ |
|
if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ |
|
x *= two54; |
|
hx = __HI(x); |
|
k = ((hx&0x7ff00000)>>20) - 54; |
|
if (n< -50000) return tiny*x; /*underflow*/ |
|
} |
|
if (k==0x7ff) return x+x; /* NaN or Inf */ |
|
k = k+n; |
|
if (k > 0x7fe) return huge*ieee_copysign(huge,x); /* overflow */ |
|
if (k > 0) /* normal result */ |
|
{__HI(x) = (hx&0x800fffff)|(k<<20); return x;} |
|
if (k <= -54) |
|
if (n > 50000) /* in case integer overflow in n+k */ |
|
return huge*ieee_copysign(huge,x); /*overflow*/ |
|
else return tiny*ieee_copysign(tiny,x); /*underflow*/ |
|
k += 54; /* subnormal result */ |
|
__HI(x) = (hx&0x800fffff)|(k<<20); |
|
return x*twom54; |
|
}
|
|
|