Split int/float division cases for efficiency, make it work even if C compiler takes...
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 29 Mar 2009 01:20:15 +0000 (18:20 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 29 Mar 2009 01:20:15 +0000 (18:20 -0700)
Cython/Compiler/ExprNodes.py

index b3c2503c55befd8eecbf1c02544a5bfe4ccc3f13..7612003ad6646d5871f9a41ef58d806d843389e5 100644 (file)
@@ -4249,7 +4249,7 @@ class DivNode(NumBinopNode):
                                     or not self.type.signed
                                     or self.type.is_float)
             if not self.cdivision:
-                code.globalstate.use_utility_code(div_utility_code.specialize(self.type))
+                code.globalstate.use_utility_code(div_int_utility_code.specialize(self.type))
         NumBinopNode.generate_evaluation_code(self, code)
         if not self.type.is_pyobject and code.globalstate.directives['cdivision_warnings']:
             self.generate_div_warning_code(code)
@@ -4294,11 +4294,10 @@ class ModNode(DivNode):
                 self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
             if not self.cdivision:
                 if self.type.is_int:
-                    code.globalstate.use_utility_code(mod_int_helper_macro)
-                    math_h_modifier = '__Pyx_INT'
+                    code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
                 else:
-                    math_h_modifier = self.type.math_h_modifier
-                code.globalstate.use_utility_code(mod_utility_code.specialize(self.type, math_h_modifier=math_h_modifier))
+                    code.globalstate.use_utility_code(
+                        mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
         NumBinopNode.generate_evaluation_code(self, code)
         if not self.type.is_pyobject and code.globalstate.directives['cdivision_warnings']:
             self.generate_div_warning_code(code)
@@ -5705,32 +5704,40 @@ static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
 
 # ------------------------------ Division ------------------------------------
 
-# This is so we can treat floating point and integer mod simultaneously. 
-mod_int_helper_macro = UtilityCode(proto="""
-#define fmod__Pyx_INT(a, b) ((a) % (b))
+div_int_utility_code = UtilityCode(
+proto="""
+static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
+""",
+impl="""
+static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
+    %(type)s q = a / b;
+    %(type)s r = a - q*b;
+    q -= ((r != 0) & ((r ^ b) < 0));
+    return q;
+}
 """)
 
-mod_utility_code = UtilityCode(
+mod_int_utility_code = UtilityCode(
 proto="""
 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
 """,
 impl="""
 static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
-    %(type)s res = fmod%(math_h_modifier)s(a, b);
-    res += ((res != 0) & ((a < 0) ^ (b < 0))) * b;
-    return res;
+    %(type)s r = a %% b;
+    r += ((r != 0) & ((r ^ b) < 0)) * b;
+    return r;
 }
 """)
 
-div_utility_code = UtilityCode(
+mod_float_utility_code = UtilityCode(
 proto="""
-static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s, %(type)s); /* proto */
+static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
 """,
 impl="""
-static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) {
-    %(type)s q = a / b;
-    q -= ((q*b != a) & ((a < 0) ^ (b < 0)));
-    return q;
+static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
+    %(type)s r = fmod%(math_h_modifier)s(a, b);
+    r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
+    return r;
 }
 """)