Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r49031:df7f0844e6b4
Date: 2011-11-09 18:13 +0100
http://bitbucket.org/pypy/pypy/changeset/df7f0844e6b4/

Log:    Tweak for the common case: use isfinite() more often, and only fall
        back to checking isnan() and isinf() if it returns False.

diff --git a/pypy/rpython/lltypesystem/module/ll_math.py 
b/pypy/rpython/lltypesystem/module/ll_math.py
--- a/pypy/rpython/lltypesystem/module/ll_math.py
+++ b/pypy/rpython/lltypesystem/module/ll_math.py
@@ -136,10 +136,12 @@
     Windows, FreeBSD and alpha Tru64 are amongst platforms that don't
     always follow C99.
     """
-    if isnan(x) or isnan(y):
+    if isnan(x):
         return NAN
 
-    if isinf(y):
+    if not isfinite(y):
+        if isnan(y):
+            return NAN
         if isinf(x):
             if math_copysign(1.0, x) == 1.0:
                 # atan2(+-inf, +inf) == +-pi/4
@@ -168,7 +170,7 @@
 
 def ll_math_frexp(x):
     # deal with special cases directly, to sidestep platform differences
-    if isnan(x) or isinf(x) or not x:
+    if not isfinite(x) or not x:
         mantissa = x
         exponent = 0
     else:
@@ -185,7 +187,7 @@
 INT_MIN = int(-2**31)
 
 def ll_math_ldexp(x, exp):
-    if x == 0.0 or isinf(x) or isnan(x):
+    if x == 0.0 or not isfinite(x):
         return x    # NaNs, zeros and infinities are returned unchanged
     if exp > INT_MAX:
         # overflow (64-bit platforms only)
@@ -209,10 +211,11 @@
 def ll_math_modf(x):
     # some platforms don't do the right thing for NaNs and
     # infinities, so we take care of special cases directly.
-    if isinf(x):
-        return (math_copysign(0.0, x), x)
-    elif isnan(x):
-        return (x, x)
+    if not isfinite(x):
+        if isnan(x):
+            return (x, x)
+        else:   # isinf(x)
+            return (math_copysign(0.0, x), x)
     intpart_p = lltype.malloc(rffi.DOUBLEP.TO, 1, flavor='raw')
     try:
         fracpart = math_modf(x, intpart_p)
@@ -250,16 +253,17 @@
     _error_reset()
     r = math_hypot(x, y)
     errno = rposix.get_errno()
-    if isnan(r):
-        if isnan(x) or isnan(y):
-            errno = 0
-        else:
-            errno = EDOM
-    elif isinf(r):
-        if isinf(x) or isnan(x) or isinf(y) or isnan(y):
-            errno = 0
-        else:
-            errno = ERANGE
+    if not isfinite(r):
+        if isnan(r):
+            if isnan(x) or isnan(y):
+                errno = 0
+            else:
+                errno = EDOM
+        else:  # isinf(r)
+            if isfinite(x) and isfinite(y):
+                errno = ERANGE
+            else:
+                errno = 0
     if errno:
         _likely_raise(errno, r)
     return r
@@ -269,30 +273,30 @@
     # deal directly with IEEE specials, to cope with problems on various
     # platforms whose semantics don't exactly match C99
 
-    if isnan(x):
-        if y == 0.0:
-            return 1.0   # NaN**0 = 1
-        return x
-
-    elif isnan(y):
+    if isnan(y):
         if x == 1.0:
             return 1.0   # 1**Nan = 1
         return y
 
-    elif isinf(x):
-        odd_y = not isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0
-        if y > 0.0:
-            if odd_y:
-                return x
-            return math_fabs(x)
-        elif y == 0.0:
-            return 1.0
-        else:   # y < 0.0
-            if odd_y:
-                return math_copysign(0.0, x)
-            return 0.0
+    if not isfinite(x):
+        if isnan(x):
+            if y == 0.0:
+                return 1.0   # NaN**0 = 1
+            return x
+        else:   # isinf(x)
+            odd_y = not isinf(y) and math_fmod(math_fabs(y), 2.0) == 1.0
+            if y > 0.0:
+                if odd_y:
+                    return x
+                return math_fabs(x)
+            elif y == 0.0:
+                return 1.0
+            else:   # y < 0.0
+                if odd_y:
+                    return math_copysign(0.0, x)
+                return 0.0
 
-    elif isinf(y):
+    if isinf(y):
         if math_fabs(x) == 1.0:
             return 1.0
         elif y > 0.0 and math_fabs(x) > 1.0:
@@ -307,17 +311,18 @@
     _error_reset()
     r = math_pow(x, y)
     errno = rposix.get_errno()
-    if isnan(r):
-        # a NaN result should arise only from (-ve)**(finite non-integer)
-        errno = EDOM
-    elif isinf(r):
-        # an infinite result here arises either from:
-        # (A) (+/-0.)**negative (-> divide-by-zero)
-        # (B) overflow of x**y with x and y finite
-        if x == 0.0:
+    if not isfinite(r):
+        if isnan(r):
+            # a NaN result should arise only from (-ve)**(finite non-integer)
             errno = EDOM
-        else:
-            errno = ERANGE
+        else:   # isinf(r)
+            # an infinite result here arises either from:
+            # (A) (+/-0.)**negative (-> divide-by-zero)
+            # (B) overflow of x**y with x and y finite
+            if x == 0.0:
+                errno = EDOM
+            else:
+                errno = ERANGE
     if errno:
         _likely_raise(errno, r)
     return r
@@ -366,18 +371,19 @@
         r = c_func(x)
         # Error checking fun.  Copied from CPython 2.6
         errno = rposix.get_errno()
-        if isnan(r):
-            if isnan(x):
-                errno = 0
-            else:
-                errno = EDOM
-        elif isinf(r):
-            if isinf(x) or isnan(x):
-                errno = 0
-            elif can_overflow:
-                errno = ERANGE
-            else:
-                errno = EDOM
+        if not isfinite(r):
+            if isnan(r):
+                if isnan(x):
+                    errno = 0
+                else:
+                    errno = EDOM
+            else:  # isinf(r)
+                if not isfinite(x):
+                    errno = 0
+                elif can_overflow:
+                    errno = ERANGE
+                else:
+                    errno = EDOM
         if errno:
             _likely_raise(errno, r)
         return r
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to