view src/libm/s_scalbn.c @ 5006:8e8876e4aec6

Include windows.h in SDL_atomic.h by default, but don't include the atomic API in SDL.h This allows all SDL code to take advantage of the atomic intrinsics on Windows, but doesn't cause applications just including SDL.h to pull in windows.h
author Sam Lantinga <slouken@libsdl.org>
date Sun, 16 Jan 2011 17:45:42 -0800
parents 9ac6f0782dd6
children
line wrap: on
line source

/* @(#)s_scalbn.c 5.1 93/09/24 */
/*
 * ====================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 * Developed at SunPro, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice
 * is preserved.
 * ====================================================
 */

#if defined(LIBM_SCCS) && !defined(lint)
static const char rcsid[] =
    "$NetBSD: s_scalbn.c,v 1.8 1995/05/10 20:48:08 jtc Exp $";
#endif

/*
 * scalbn (double x, int n)
 * scalbn(x,n) returns x* 2**n  computed by  exponent
 * manipulation rather than by actually performing an
 * exponentiation or a multiplication.
 */

#include "math.h"
#include "math_private.h"

libm_hidden_proto(copysign)
#ifdef __STDC__
     static const double
#else
     static double
#endif
       two54 = 1.80143985094819840000e+16,      /* 0x43500000, 0x00000000 */
         twom54 = 5.55111512312578270212e-17,   /* 0x3C900000, 0x00000000 */
         huge_val = 1.0e+300, tiny = 1.0e-300;

libm_hidden_proto(scalbn)
#ifdef __STDC__
     double scalbn(double x, int n)
#else
     double scalbn(x, n)
     double x;
     int n;
#endif
{
    int32_t k, hx, lx;
    EXTRACT_WORDS(hx, lx, x);
    k = (hx & 0x7ff00000) >> 20;        /* extract exponent */
    if (k == 0) {               /* 0 or subnormal x */
        if ((lx | (hx & 0x7fffffff)) == 0)
            return x;           /* +-0 */
        x *= two54;
        GET_HIGH_WORD(hx, 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_val * copysign(huge_val, x);        /* overflow  */
    if (k > 0) {                /* normal result */
        SET_HIGH_WORD(x, (hx & 0x800fffff) | (k << 20));
        return x;
    }
    if (k <= -54) {
        if (n > 50000)          /* in case integer overflow in n+k */
            return huge_val * copysign(huge_val, x);    /*overflow */
        else
            return tiny * copysign(tiny, x);    /*underflow */
    }
    k += 54;                    /* subnormal result */
    SET_HIGH_WORD(x, (hx & 0x800fffff) | (k << 20));
    return x * twom54;
}

libm_hidden_def(scalbn)