diff options
Diffstat (limited to 'libm/e_scalb.c')
-rw-r--r-- | libm/e_scalb.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/libm/e_scalb.c b/libm/e_scalb.c index f43fe6dd5..db3639683 100644 --- a/libm/e_scalb.c +++ b/libm/e_scalb.c @@ -17,6 +17,7 @@ #include "math.h" #include "math_private.h" +#include <errno.h> #ifdef _SCALB_INT double attribute_hidden __ieee754_scalb(double x, int fn) @@ -26,6 +27,7 @@ double attribute_hidden __ieee754_scalb(double x, double fn) { #ifdef _SCALB_INT return scalbn(x,fn); +//TODO: just alias it to scalbn? #else if (isnan(x)||isnan(fn)) return x*fn; if (!isfinite(fn)) { @@ -38,3 +40,32 @@ double attribute_hidden __ieee754_scalb(double x, double fn) return scalbn(x,(int)fn); #endif } + +/* + * wrapper scalb(double x, double fn) is provide for + * passing various standard test suite. One + * should use scalbn() instead. + */ +#ifndef _IEEE_LIBM +# ifdef _SCALB_INT +double scalb(double x, int fn) +# else +double scalb(double x, double fn) +# endif +{ + double z = __ieee754_scalb(x, fn); + if (_LIB_VERSION == _IEEE_) + return z; + if (!(isfinite(z) || isnan(z)) && isfinite(x)) + return __kernel_standard(x, (double)fn, 32); /* scalb overflow */ + if (z == 0.0 && z != x) + return __kernel_standard(x, (double)fn, 33); /* scalb underflow */ +# ifndef _SCALB_INT + if (!isfinite(fn)) + errno = ERANGE; +# endif + return z; +} +#else +strong_alias(__ieee754_scalb, scalb) +#endif |