1__doc__ = u""" 2>>> v = [(17, 10), (-17, 10), (-17, -10), (17, -10)] 3>>> standard = [(a % b) for a, b in v] 4>>> standard 5[7, 3, -7, -3] 6>>> [mod_int_py(a, b) for a, b in v] == standard 7True 8>>> [mod_short_py(a, b) for a, b in v] == standard 9True 10>>> [mod_float_py(a, b) for a, b in v] == standard 11True 12>>> [mod_double_py(a, b) for a, b in v] == standard 13True 14 15>>> [mod_int_c(a, b) for a, b in v] 16[7, -7, -7, 7] 17>>> [mod_float_c(a, b) for a, b in v] 18[7.0, -7.0, -7.0, 7.0] 19>>> [mod_double_c(a, b) for a, b in v] 20[7.0, -7.0, -7.0, 7.0] 21 22>>> [div_int_py(a, b) for a, b in v] 23[1, -2, 1, -2] 24>>> [div_int_c(a, b) for a, b in v] 25[1, -1, 1, -1] 26 27>>> [test_cdiv_cmod(a, b) for a, b in v] 28[(1, 7), (-1, -7), (1, -7), (-1, 7)] 29 30>>> all([mod_int_py(a,b) == a % b for a in range(-10, 10) for b in range(-10, 10) if b != 0]) 31True 32>>> all([div_int_py(a,b) == a // b for a in range(-10, 10) for b in range(-10, 10) if b != 0]) 33True 34""" 35 36import warnings 37orig_showwarning = warnings.showwarning 38 39true_py_functions = {} 40exec "def simple_warn(msg, *args): print(msg)" in true_py_functions 41simple_warn = true_py_functions['simple_warn'] 42del true_py_functions 43 44 45def _all(seq): 46 for x in seq: 47 if not x: 48 return False 49 return True 50 51try: 52 all 53except NameError: 54 all = _all 55 56 57cimport cython 58 59@cython.cdivision(False) 60def mod_int_py(int a, int b): 61 return a % b 62 63@cython.cdivision(False) 64def mod_short_py(short a, short b): 65 return a % b 66 67@cython.cdivision(False) 68def mod_double_py(double a, double b): 69 return a % b 70 71@cython.cdivision(False) 72def mod_float_py(float a, float b): 73 return a % b 74 75@cython.cdivision(True) 76def mod_int_c(int a, int b): 77 return a % b 78 79@cython.cdivision(True) 80def mod_float_c(float a, float b): 81 return a % b 82 83@cython.cdivision(True) 84def mod_double_c(double a, double b): 85 return a % b 86 87 88@cython.cdivision(False) 89def div_int_py(int a, int b): 90 return a // b 91 92@cython.cdivision(True) 93def div_int_c(int a, int b): 94 return a // b 95 96 97@cython.cdivision(False) 98def test_cdiv_cmod(short a, short b): 99 cdef short q = cython.cdiv(a, b) 100 cdef short r = cython.cmod(a, b) 101 return q, r 102 103@cython.cdivision(True) 104@cython.cdivision_warnings(True) 105def mod_int_c_warn(int a, int b): 106 """ 107 >>> warnings.showwarning = simple_warn 108 >>> mod_int_c_warn(-17, 10) 109 division with oppositely signed operands, C and Python semantics differ 110 -7 111 >>> warnings.showwarning = orig_showwarning 112 """ 113 return a % b 114 115@cython.cdivision(True) 116@cython.cdivision_warnings(True) 117def div_int_c_warn(int a, int b): 118 """ 119 >>> warnings.showwarning = simple_warn 120 >>> div_int_c_warn(-17, 10) 121 division with oppositely signed operands, C and Python semantics differ 122 -1 123 >>> warnings.showwarning = orig_showwarning 124 """ 125 return a // b 126 127@cython.cdivision(False) 128@cython.cdivision_warnings(True) 129def complex_expression(int a, int b, int c, int d): 130 """ 131 >>> warnings.showwarning = simple_warn 132 >>> complex_expression(-150, 20, 19, -7) 133 verbose_call(20) 134 division with oppositely signed operands, C and Python semantics differ 135 verbose_call(19) 136 division with oppositely signed operands, C and Python semantics differ 137 -2 138 >>> warnings.showwarning = orig_showwarning 139 """ 140 return (a // verbose_call(b)) % (verbose_call(c) // d) 141 142cdef int verbose_call(int x): 143 print u"verbose_call(%s)" % x 144 return x 145 146 147# These may segfault with cdivision 148 149@cython.cdivision(False) 150def mod_div_zero_int(int a, int b, int c): 151 """ 152 >>> mod_div_zero_int(25, 10, 2) 153 verbose_call(5) 154 2 155 >>> print(mod_div_zero_int(25, 10, 0)) 156 verbose_call(5) 157 integer division or modulo by zero 158 >>> print(mod_div_zero_int(25, 0, 0)) 159 integer division or modulo by zero 160 """ 161 try: 162 return verbose_call(a % b) / c 163 except ZeroDivisionError, ex: 164 return unicode(ex) 165 166@cython.cdivision(False) 167def mod_div_zero_float(float a, float b, float c): 168 """ 169 >>> mod_div_zero_float(25, 10, 2) 170 2.5 171 >>> print(mod_div_zero_float(25, 10, 0)) 172 float division 173 >>> print(mod_div_zero_float(25, 0, 0)) 174 float divmod() 175 """ 176 try: 177 return (a % b) / c 178 except ZeroDivisionError, ex: 179 return unicode(ex) 180 181@cython.cdivision(False) 182def py_div_long(long a, long b): 183 """ 184 >>> py_div_long(-5, -1) 185 5 186 >>> import sys 187 >>> maxint = getattr(sys, ((sys.version_info[0] >= 3) and 'maxsize' or 'maxint')) 188 >>> py_div_long(-maxint-1, -1) # doctest: +ELLIPSIS 189 Traceback (most recent call last): 190 ... 191 OverflowError: ... 192 """ 193 return a / b 194 195def c_div_const_test(a, b): 196 """ 197 >>> c_div_const_test(5, 3) 198 1 199 """ 200 return c_div_const(a, b) 201 202cdef long c_div_const(const long a, int b): 203 cdef long c = a / b 204 return c 205