Changeset View
Changeset View
Standalone View
Standalone View
lib/msun/src/s_scalbnf.c
/* s_scalbnf.c -- float version of s_scalbn.c. | #include <math.h> | ||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. | #include <stdint.h> | ||||
*/ | |||||
/* | float scalbnf(float x, int n) | ||||
* ==================================================== | |||||
* 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. | |||||
* ==================================================== | |||||
*/ | |||||
#include <sys/cdefs.h> | |||||
__FBSDID("$FreeBSD$"); | |||||
#include "math.h" | |||||
#include "math_private.h" | |||||
static const float | |||||
two25 = 3.355443200e+07, /* 0x4c000000 */ | |||||
twom25 = 2.9802322388e-08, /* 0x33000000 */ | |||||
huge = 1.0e+30, | |||||
tiny = 1.0e-30; | |||||
float | |||||
scalbnf (float x, int n) | |||||
{ | { | ||||
int32_t k,ix; | union {float f; uint32_t i;} u; | ||||
GET_FLOAT_WORD(ix,x); | float_t y = x; | ||||
k = (ix&0x7f800000)>>23; /* extract exponent */ | |||||
if (k==0) { /* 0 or subnormal x */ | if (n > 127) { | ||||
if ((ix&0x7fffffff)==0) return x; /* +-0 */ | y *= 0x1p127f; | ||||
x *= two25; | n -= 127; | ||||
GET_FLOAT_WORD(ix,x); | if (n > 127) { | ||||
k = ((ix&0x7f800000)>>23) - 25; | y *= 0x1p127f; | ||||
if (n< -50000) return tiny*x; /*underflow*/ | n -= 127; | ||||
if (n > 127) | |||||
n = 127; | |||||
} | } | ||||
if (k==0xff) return x+x; /* NaN or Inf */ | } else if (n < -126) { | ||||
k = k+n; | y *= 0x1p-126f * 0x1p24f; | ||||
if (k > 0xfe) return huge*copysignf(huge,x); /* overflow */ | n += 126 - 24; | ||||
if (k > 0) /* normal result */ | if (n < -126) { | ||||
{SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} | y *= 0x1p-126f * 0x1p24f; | ||||
if (k <= -25) { | n += 126 - 24; | ||||
if (n > 50000) /* in case integer overflow in n+k */ | if (n < -126) | ||||
return huge*copysignf(huge,x); /*overflow*/ | n = -126; | ||||
else | |||||
return tiny*copysignf(tiny,x); /*underflow*/ | |||||
} | } | ||||
k += 25; /* subnormal result */ | } | ||||
SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); | u.i = (uint32_t)(0x7f+n)<<23; | ||||
return x*twom25; | x = y * u.f; | ||||
return x; | |||||
} | } | ||||
__strong_reference(scalbnf, ldexpf); | __strong_reference(scalbnf, ldexpf); |