12fe8fb19SBen Gras /* s_scalbnf.c -- float version of s_scalbn.c.
22fe8fb19SBen Gras * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
32fe8fb19SBen Gras */
42fe8fb19SBen Gras
52fe8fb19SBen Gras /*
62fe8fb19SBen Gras * ====================================================
72fe8fb19SBen Gras * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
82fe8fb19SBen Gras *
92fe8fb19SBen Gras * Developed at SunPro, a Sun Microsystems, Inc. business.
102fe8fb19SBen Gras * Permission to use, copy, modify, and distribute this
112fe8fb19SBen Gras * software is freely granted, provided that this notice
122fe8fb19SBen Gras * is preserved.
132fe8fb19SBen Gras * ====================================================
142fe8fb19SBen Gras */
152fe8fb19SBen Gras
162fe8fb19SBen Gras #include <sys/cdefs.h>
172fe8fb19SBen Gras #if defined(LIBM_SCCS) && !defined(lint)
18*84d9c625SLionel Sambuc __RCSID("$NetBSD: s_scalbnf.c,v 1.12 2013/05/20 19:40:09 joerg Exp $");
192fe8fb19SBen Gras #endif
202fe8fb19SBen Gras
212fe8fb19SBen Gras #include "namespace.h"
222fe8fb19SBen Gras #include "math.h"
232fe8fb19SBen Gras #include "math_private.h"
242fe8fb19SBen Gras
25*84d9c625SLionel Sambuc #ifndef _LP64
26*84d9c625SLionel Sambuc __strong_alias(_scalbnf, _scalblnf)
272fe8fb19SBen Gras #endif
28*84d9c625SLionel Sambuc __weak_alias(scalbnf, _scalbnf)
29*84d9c625SLionel Sambuc __weak_alias(scalblnf, _scalblnf)
30*84d9c625SLionel Sambuc __weak_alias(ldexpf, _scalbnf)
312fe8fb19SBen Gras
322fe8fb19SBen Gras static const float
33*84d9c625SLionel Sambuc two25 = 0x1.0p25, /* 0x4c000000 */
34*84d9c625SLionel Sambuc twom25 = 0x1.0p-25, /* 0x33000000 */
352fe8fb19SBen Gras huge = 1.0e+30,
362fe8fb19SBen Gras tiny = 1.0e-30;
372fe8fb19SBen Gras
38*84d9c625SLionel Sambuc #ifdef _LP64
392fe8fb19SBen Gras float
scalbnf(float x,int n)402fe8fb19SBen Gras scalbnf(float x, int n)
412fe8fb19SBen Gras {
42*84d9c625SLionel Sambuc return scalblnf(x, n);
43*84d9c625SLionel Sambuc }
44*84d9c625SLionel Sambuc #endif
45*84d9c625SLionel Sambuc
46*84d9c625SLionel Sambuc float
scalblnf(float x,long n)47*84d9c625SLionel Sambuc scalblnf(float x, long n)
48*84d9c625SLionel Sambuc {
492fe8fb19SBen Gras int32_t k,ix;
502fe8fb19SBen Gras GET_FLOAT_WORD(ix,x);
512fe8fb19SBen Gras k = (ix&0x7f800000)>>23; /* extract exponent */
522fe8fb19SBen Gras if (k==0) { /* 0 or subnormal x */
532fe8fb19SBen Gras if ((ix&0x7fffffff)==0) return x; /* +-0 */
542fe8fb19SBen Gras x *= two25;
552fe8fb19SBen Gras GET_FLOAT_WORD(ix,x);
562fe8fb19SBen Gras k = ((ix&0x7f800000)>>23) - 25;
572fe8fb19SBen Gras if (n< -50000) return tiny*x; /*underflow*/
582fe8fb19SBen Gras }
592fe8fb19SBen Gras if (k==0xff) return x+x; /* NaN or Inf */
602fe8fb19SBen Gras k = k+n;
612fe8fb19SBen Gras if (k > 0xfe) return huge*copysignf(huge,x); /* overflow */
622fe8fb19SBen Gras if (k > 0) /* normal result */
632fe8fb19SBen Gras {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;}
642fe8fb19SBen Gras if (k <= -25) {
652fe8fb19SBen Gras if (n > 50000) /* in case integer overflow in n+k */
662fe8fb19SBen Gras return huge*copysignf(huge,x); /*overflow*/
672fe8fb19SBen Gras else return tiny*copysignf(tiny,x); /*underflow*/
682fe8fb19SBen Gras }
692fe8fb19SBen Gras k += 25; /* subnormal result */
702fe8fb19SBen Gras SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23));
712fe8fb19SBen Gras return x*twom25;
722fe8fb19SBen Gras }
73