#include "ieeeftn.h"

#if STDC
REAL
setxp(REAL *x, INTEGER *n)
#else /* NOT STDC */
REAL
setxp(x,n)			/* return (fraction of x) * base**n */
REAL *x;			/* i.e. replace the exponent field of x */
INTEGER *n;
#endif /* STDC */
{
    REAL_PARTS w;

    if (isden(x))			/* then x is denormalized */
        w.r = *x * BASE_TO_THE_T_SP;	/* so must first normalize fraction */
    else
	w.r = *x;			/* x is normal, NaN, or Inf */
    if (w.r == 0.0)			/* zeroes must be left intact */
        /* NO-OP */;
    else if (isnan(x))			/* NaNs must be left intact */
        /* NO-OP */;
    else if (isinf(x))			/* Infs must be left intact */
        /* NO-OP */;
    else if (*n <= (EXPONENT_DENORM_SP - T_SP)) /* underflow to zero */
	w.r = (REAL)0.0;
    else if (*n <= EXPONENT_DENORM_SP)	/* generate denormalized value */
    {
	w.i &= ~EXPONENT_MASK_SP;	/* clear exponent field */
	w.i |= SET_EXPONENT_SP(*n + T_SP);	/* set new exponent */
					/* of scaled normal value */
	w.r /= BASE_TO_THE_T_SP;	/* and denormalize by division */
    }
    else if (*n >= EXPONENT_INFNAN_SP)	/* generate infinity */
	w.i = ISNEG_SP(w.i) ? NegInf_SP : Inf_SP;
    else				/* result is normal number */
    {					/* and exponent in range */
	w.i &= ~EXPONENT_MASK_SP;	/* clear exponent field */
	w.i |= SET_EXPONENT_SP(*n);	/* set new exponent */
    }

    return (w.r);
}
