view src/libm/s_scalbn.c @ 3468:789b97008d8a

My first OpenGL shader! Momma will be so proud! This shader implements the software renderer mask semantics where the source pixel is multiplied by the color and alpha modulation values and then any pixel with non-zero alpha is fully opaque. The OpenGL renderer on Mac OS X now passes all the automated render tests! :)
author Sam Lantinga <slouken@libsdl.org>
date Sat, 21 Nov 2009 05:29:31 +0000
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)