diff options
| author | Bdale Garbee <bdale@gag.com> | 2013-12-19 01:38:40 -0700 | 
|---|---|---|
| committer | Bdale Garbee <bdale@gag.com> | 2013-12-19 01:38:40 -0700 | 
| commit | 575bbaf976c5840fd0e308549c45a466fdec1352 (patch) | |
| tree | 11bfb498348bf7687bffc24699c4b1a998988ee4 /src/math/sf_scalbn.c | |
| parent | b825116df173b77e2cab217a7b76112c742f9279 (diff) | |
| parent | bc3610d8cecbfed40c62d4dcb93fc9a4d2a7c9e3 (diff) | |
Merge branch 'branch-1.3' into debian
Conflicts:
	ChangeLog
	altoslib/AltosRecordMM.java
	altosui/Makefile.am
	altosui/altos-windows.nsi.in
	configure.ac
	debian/changelog
	debian/control
	doc/Makefile
	doc/altusmetrum.xsl
	doc/release-notes-1.2.1.xsl
	doc/release-notes-1.2.xsl
Diffstat (limited to 'src/math/sf_scalbn.c')
| -rw-r--r-- | src/math/sf_scalbn.c | 86 | 
1 files changed, 86 insertions, 0 deletions
diff --git a/src/math/sf_scalbn.c b/src/math/sf_scalbn.c new file mode 100644 index 00000000..70006001 --- /dev/null +++ b/src/math/sf_scalbn.c @@ -0,0 +1,86 @@ +/* sf_scalbn.c -- float version of s_scalbn.c. + * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + */ + +/* + * ==================================================== + * 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 "fdlibm.h" +#include <limits.h> +#include <float.h> + +#if INT_MAX > 50000 +#define OVERFLOW_INT 50000 +#else +#define OVERFLOW_INT 30000 +#endif + +#ifdef __STDC__ +static const float +#else +static float +#endif +two25   =  3.355443200e+07,	/* 0x4c000000 */ +twom25  =  2.9802322388e-08,	/* 0x33000000 */ +huge   = 1.0e+30, +tiny   = 1.0e-30; + +#ifdef __STDC__ +	float scalbnf (float x, int n) +#else +	float scalbnf (x,n) +	float x; int n; +#endif +{ +	__int32_t  k,ix; +	__uint32_t hx; + +	GET_FLOAT_WORD(ix,x); +	hx = ix&0x7fffffff; +        k = hx>>23;		/* extract exponent */ +	if (FLT_UWORD_IS_ZERO(hx)) +	    return x; +        if (!FLT_UWORD_IS_FINITE(hx)) +	    return x+x;		/* NaN or Inf */ +        if (FLT_UWORD_IS_SUBNORMAL(hx)) { +	    x *= two25; +	    GET_FLOAT_WORD(ix,x); +	    k = ((ix&0x7f800000)>>23) - 25;  +            if (n< -50000) return tiny*x; 	/*underflow*/ +        } +        k = k+n;  +        if (k > FLT_LARGEST_EXP) return huge*copysignf(huge,x); /* overflow  */ +        if (k > 0) 				/* normal result */ +	    {SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); return x;} +        if (k < FLT_SMALLEST_EXP) { +            if (n > OVERFLOW_INT) 	/* in case integer overflow in n+k */ +		return huge*copysignf(huge,x);	/*overflow*/ +	    else return tiny*copysignf(tiny,x);	/*underflow*/ +        } +        k += 25;				/* subnormal result */ +	SET_FLOAT_WORD(x,(ix&0x807fffff)|(k<<23)); +        return x*twom25; +} + +#ifdef _DOUBLE_IS_32BITS + +#ifdef __STDC__ +	double scalbn(double x, int n) +#else +	double scalbn(x,n) +	double x; +	int n; +#endif +{ +	return (double) scalbnf((float) x, n); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */  | 
