From: Robert Bradshaw Date: Sun, 29 Mar 2009 01:20:15 +0000 (-0700) Subject: Split int/float division cases for efficiency, make it work even if C compiler takes... X-Git-Tag: 0.12.alpha0~334^2~2^2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=2779f4bd8f916d21f3de5dd352f8b3a8dc0082ce;p=cython.git Split int/float division cases for efficiency, make it work even if C compiler takes floor (don't know of any that do). --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index b3c2503c..7612003a 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -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; } """)