src/libm/s_scalbn.c
changeset 11683 48bcba563d9c
parent 7678 286c42d7c5ed
child 11684 eccdf37f8996
     1.1 --- a/src/libm/s_scalbn.c	Sat Nov 04 15:34:14 2017 -0700
     1.2 +++ b/src/libm/s_scalbn.c	Sat Nov 04 15:53:19 2017 -0700
     1.3 @@ -1,4 +1,3 @@
     1.4 -/* @(#)s_scalbn.c 5.1 93/09/24 */
     1.5  /*
     1.6   * ====================================================
     1.7   * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
     1.8 @@ -10,70 +9,69 @@
     1.9   * ====================================================
    1.10   */
    1.11  
    1.12 -#if defined(LIBM_SCCS) && !defined(lint)
    1.13 -static const char rcsid[] =
    1.14 -    "$NetBSD: s_scalbn.c,v 1.8 1995/05/10 20:48:08 jtc Exp $";
    1.15 -#endif
    1.16 -
    1.17  /*
    1.18 - * scalbn (double x, int n)
    1.19 - * scalbn(x,n) returns x* 2**n  computed by  exponent
    1.20 + * scalbln(double x, long n)
    1.21 + * scalbln(x,n) returns x * 2**n computed by exponent
    1.22   * manipulation rather than by actually performing an
    1.23   * exponentiation or a multiplication.
    1.24   */
    1.25  
    1.26  #include "math_libm.h"
    1.27  #include "math_private.h"
    1.28 +#include <limits.h>
    1.29  
    1.30 -libm_hidden_proto(copysign)
    1.31 -#ifdef __STDC__
    1.32 -     static const double
    1.33 -#else
    1.34 -     static double
    1.35 -#endif
    1.36 -       two54 = 1.80143985094819840000e+16,      /* 0x43500000, 0x00000000 */
    1.37 -         twom54 = 5.55111512312578270212e-17,   /* 0x3C900000, 0x00000000 */
    1.38 -         huge_val = 1.0e+300, tiny = 1.0e-300;
    1.39 +static const double
    1.40 +two54  = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
    1.41 +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
    1.42 +huge   = 1.0e+300,
    1.43 +tiny   = 1.0e-300;
    1.44  
    1.45 -libm_hidden_proto(scalbn)
    1.46 -#ifdef __STDC__
    1.47 -     double scalbn(double x, int n)
    1.48 -#else
    1.49 -     double scalbn(x, n)
    1.50 -     double x;
    1.51 -     int n;
    1.52 -#endif
    1.53 +double scalbln(double x, long n)
    1.54  {
    1.55 -    int32_t k, hx, lx;
    1.56 -    EXTRACT_WORDS(hx, lx, x);
    1.57 -    k = (hx & 0x7ff00000) >> 20;        /* extract exponent */
    1.58 -    if (k == 0) {               /* 0 or subnormal x */
    1.59 -        if ((lx | (hx & 0x7fffffff)) == 0)
    1.60 -            return x;           /* +-0 */
    1.61 -        x *= two54;
    1.62 -        GET_HIGH_WORD(hx, x);
    1.63 -        k = ((hx & 0x7ff00000) >> 20) - 54;
    1.64 -        if (n < -50000)
    1.65 -            return tiny * x;    /* underflow */
    1.66 -    }
    1.67 -    if (k == 0x7ff)
    1.68 -        return x + x;           /* NaN or Inf */
    1.69 -    k = k + n;
    1.70 -    if (k > 0x7fe)
    1.71 -        return huge_val * copysign(huge_val, x);        /* overflow  */
    1.72 -    if (k > 0) {                /* normal result */
    1.73 -        SET_HIGH_WORD(x, (hx & 0x800fffff) | (k << 20));
    1.74 -        return x;
    1.75 -    }
    1.76 -    if (k <= -54) {
    1.77 -        if (n > 50000)          /* in case integer overflow in n+k */
    1.78 -            return huge_val * copysign(huge_val, x);    /* overflow */
    1.79 -        else
    1.80 -            return tiny * copysign(tiny, x);    /* underflow */
    1.81 -    }
    1.82 -    k += 54;                    /* subnormal result */
    1.83 -    SET_HIGH_WORD(x, (hx & 0x800fffff) | (k << 20));
    1.84 -    return x * twom54;
    1.85 +	int32_t k, hx, lx;
    1.86 +
    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)
    1.91 +			return x; /* +-0 */
    1.92 +		x *= two54;
    1.93 +		GET_HIGH_WORD(hx, x);
    1.94 +		k = ((hx & 0x7ff00000) >> 20) - 54;
    1.95 +	}
    1.96 +	if (k == 0x7ff)
    1.97 +		return x + x; /* NaN or Inf */
    1.98 +	k = k + n;
    1.99 +	if (k > 0x7fe)
   1.100 +		return huge * copysign(huge, x); /* overflow */
   1.101 +	if (n < -50000)
   1.102 +		return tiny * copysign(tiny, x); /* underflow */
   1.103 +	if (k > 0) { /* normal result */
   1.104 +		SET_HIGH_WORD(x, (hx & 0x800fffff) | (k << 20));
   1.105 +		return x;
   1.106 +	}
   1.107 +	if (k <= -54) {
   1.108 +		if (n > 50000) /* in case integer overflow in n+k */
   1.109 +			return huge * copysign(huge, x); /* overflow */
   1.110 +		return tiny * copysign(tiny, x); /* underflow */
   1.111 +	}
   1.112 +	k += 54; /* subnormal result */
   1.113 +	SET_HIGH_WORD(x, (hx & 0x800fffff) | (k << 20));
   1.114 +	return x * twom54;
   1.115  }
   1.116 +libm_hidden_def(scalbln)
   1.117  
   1.118 +#if LONG_MAX == INT_MAX
   1.119 +/* strong_alias(scalbln, scalbn) - "error: conflicting types for 'scalbn'"
   1.120 + * because it tries to declare "typeof(scalbln) scalbn;"
   1.121 + * which tries to give "long" parameter to scalbn.
   1.122 + * Doing it by hand:
   1.123 + */
   1.124 +__typeof(scalbn) scalbn __attribute__((alias("scalbln")));
   1.125 +#else
   1.126 +double scalbn(double x, int n)
   1.127 +{
   1.128 +	return scalbln(x, n);
   1.129 +}
   1.130 +#endif
   1.131  libm_hidden_def(scalbn)