about summary refs log tree commit diff
path: root/math/w_scalb.c
diff options
context:
space:
mode:
Diffstat (limited to 'math/w_scalb.c')
-rw-r--r--math/w_scalb.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/math/w_scalb.c b/math/w_scalb.c
index dbfefaf9d5..0f1e2df8ef 100644
--- a/math/w_scalb.c
+++ b/math/w_scalb.c
@@ -45,9 +45,33 @@ sysv_scalb (double x, double fn)
 double
 __scalb (double x, double fn)
 {
-  return (__builtin_expect (_LIB_VERSION == _SVID_, 0)
-	  ? sysv_scalb (x, fn)
-	  : __ieee754_scalb (x, fn));
+  if (__glibc_unlikely (_LIB_VERSION == _SVID_))
+    return sysv_scalb (x, fn);
+  else
+    {
+      double z = __ieee754_scalb (x, fn);
+
+      if (__glibc_unlikely (!__finite (z) || z == 0.0))
+	{
+	  if (__isnan (z))
+	    {
+	      if (!__isnan (x) && !__isnan (fn))
+		__set_errno (EDOM);
+	    }
+	  else if (__isinf_ns (z))
+	    {
+	      if (!__isinf_ns (x) && !__isinf_ns (fn))
+		__set_errno (ERANGE);
+	    }
+	  else
+	    {
+	      /* z == 0.  */
+	      if (x != 0.0 && !__isinf_ns (fn))
+		__set_errno (ERANGE);
+	    }
+	}
+      return z;
+    }
 }
 weak_alias (__scalb, scalb)
 #ifdef NO_LONG_DOUBLE