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