Commit 43fe5b88 authored by Stefan Behnel's avatar Stefan Behnel

simplify abs() optimisation for C integers and fix it for the most negative int/long value

parent 9f965289
......@@ -19,16 +19,16 @@ proto = """
abs_int_utility_code = UtilityCode(
proto = '''
#if HAVE_LONG_LONG && defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define __Pyx_abs_int(x) \
((sizeof(x) <= sizeof(int)) ? ((unsigned int)abs(x)) : \
((sizeof(x) <= sizeof(long)) ? ((unsigned long)labs(x)) : \
((unsigned PY_LONG_LONG)llabs(x))))
#else
#define __Pyx_abs_int(x) \
((sizeof(x) <= sizeof(int)) ? ((unsigned int)abs(x)) : ((unsigned long)labs(x)))
#endif
#define __Pyx_abs_long(x) __Pyx_abs_int(x)
static CYTHON_INLINE unsigned int __Pyx_abs_int(int x) {
if (unlikely(x == -INT_MAX-1))
return ((unsigned int)INT_MAX) + 1U;
return (unsigned int) abs(x);
}
static CYTHON_INLINE unsigned long __Pyx_abs_long(long x) {
if (unlikely(x == -LONG_MAX-1))
return ((unsigned long)LONG_MAX) + 1U;
return (unsigned long) labs(x);
}
''')
iter_next_utility_code = UtilityCode.load_cached("IterNext", "ObjectHandling.c")
......
......@@ -47,6 +47,16 @@ def int_abs(int a):
"""
return abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
@cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_int']",
"//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_long']")
def uint_abs(unsigned int a):
"""
>>> uint_abs(max_int) == abs(max_int) or (max_int, uint_abs(max_int), abs(max_int))
True
"""
return abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']",
"//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_long']")
def long_abs(long a):
......@@ -64,6 +74,16 @@ def long_abs(long a):
"""
return abs(a)
@cython.test_assert_path_exists("//ReturnStatNode//NameNode[@entry.name = 'abs']")
@cython.test_fail_if_path_exists("//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_int']",
"//ReturnStatNode//NameNode[@entry.cname = '__Pyx_abs_long']")
def ulong_abs(unsigned long a):
"""
>>> ulong_abs(max_long) == abs(max_long) or (max_int, ulong_abs(max_long), abs(max_long))
True
"""
return abs(a)
def long_long_abs(long long a):
"""
>>> long_long_abs(-(2**33)) == 2**33
......
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