Commit 2779f4bd authored by Robert Bradshaw's avatar Robert Bradshaw

Split int/float division cases for efficiency, make it work even if C compiler...

Split int/float division cases for efficiency, make it work even if C compiler takes floor (don't know of any that do).
parent 0e658851
...@@ -4249,7 +4249,7 @@ class DivNode(NumBinopNode): ...@@ -4249,7 +4249,7 @@ class DivNode(NumBinopNode):
or not self.type.signed or not self.type.signed
or self.type.is_float) or self.type.is_float)
if not self.cdivision: 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) NumBinopNode.generate_evaluation_code(self, code)
if not self.type.is_pyobject and code.globalstate.directives['cdivision_warnings']: if not self.type.is_pyobject and code.globalstate.directives['cdivision_warnings']:
self.generate_div_warning_code(code) self.generate_div_warning_code(code)
...@@ -4294,11 +4294,10 @@ class ModNode(DivNode): ...@@ -4294,11 +4294,10 @@ class ModNode(DivNode):
self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed self.cdivision = code.globalstate.directives['cdivision'] or not self.type.signed
if not self.cdivision: if not self.cdivision:
if self.type.is_int: if self.type.is_int:
code.globalstate.use_utility_code(mod_int_helper_macro) code.globalstate.use_utility_code(mod_int_utility_code.specialize(self.type))
math_h_modifier = '__Pyx_INT'
else: else:
math_h_modifier = self.type.math_h_modifier code.globalstate.use_utility_code(
code.globalstate.use_utility_code(mod_utility_code.specialize(self.type, math_h_modifier=math_h_modifier)) mod_float_utility_code.specialize(self.type, math_h_modifier=self.type.math_h_modifier))
NumBinopNode.generate_evaluation_code(self, code) NumBinopNode.generate_evaluation_code(self, code)
if not self.type.is_pyobject and code.globalstate.directives['cdivision_warnings']: if not self.type.is_pyobject and code.globalstate.directives['cdivision_warnings']:
self.generate_div_warning_code(code) self.generate_div_warning_code(code)
...@@ -5705,32 +5704,40 @@ static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) { ...@@ -5705,32 +5704,40 @@ static INLINE %(type)s %(func_name)s(%(type)s b, %(type)s e) {
# ------------------------------ Division ------------------------------------ # ------------------------------ Division ------------------------------------
# This is so we can treat floating point and integer mod simultaneously. div_int_utility_code = UtilityCode(
mod_int_helper_macro = UtilityCode(proto=""" proto="""
#define fmod__Pyx_INT(a, b) ((a) % (b)) 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=""" proto="""
static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */ static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s, %(type)s); /* proto */
""", """,
impl=""" impl="""
static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) { 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); %(type)s r = a %% b;
res += ((res != 0) & ((a < 0) ^ (b < 0))) * b; r += ((r != 0) & ((r ^ b) < 0)) * b;
return res; return r;
} }
""") """)
div_utility_code = UtilityCode( mod_float_utility_code = UtilityCode(
proto=""" 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=""" impl="""
static INLINE %(type)s __Pyx_div_%(type_name)s(%(type)s a, %(type)s b) { static INLINE %(type)s __Pyx_mod_%(type_name)s(%(type)s a, %(type)s b) {
%(type)s q = a / b; %(type)s r = fmod%(math_h_modifier)s(a, b);
q -= ((q*b != a) & ((a < 0) ^ (b < 0))); r += ((r != 0) & ((r < 0) ^ (b < 0))) * b;
return q; return r;
} }
""") """)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment