@@ -139,10 +139,29 @@ fn inner_pow(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
139
139
}
140
140
141
141
fn inner_mod ( int1 : & PyInt , int2 : & PyInt , vm : & VirtualMachine ) -> PyResult {
142
- if int2. value != BigInt :: zero ( ) {
142
+ if int2. value . is_zero ( ) {
143
+ Err ( vm. new_zero_division_error ( "integer modulo by zero" . to_string ( ) ) )
144
+ } else {
143
145
Ok ( vm. ctx . new_int ( & int1. value % & int2. value ) )
146
+ }
147
+ }
148
+
149
+ fn inner_floordiv ( int1 : & PyInt , int2 : & PyInt , vm : & VirtualMachine ) -> PyResult {
150
+ if int2. value . is_zero ( ) {
151
+ Err ( vm. new_zero_division_error ( "integer division by zero" . to_string ( ) ) )
144
152
} else {
145
- Err ( vm. new_zero_division_error ( "integer modulo by zero" . to_string ( ) ) )
153
+ Ok ( vm. ctx . new_int ( int1. value . div_floor ( & int2. value ) ) )
154
+ }
155
+ }
156
+
157
+ fn inner_divmod ( int1 : & PyInt , int2 : & PyInt , vm : & VirtualMachine ) -> PyResult {
158
+ if int2. value . is_zero ( ) {
159
+ Err ( vm. new_zero_division_error ( "integer division or modulo by zero" . to_string ( ) ) )
160
+ } else {
161
+ let ( div, modulo) = int1. value . div_mod_floor ( & int2. value ) ;
162
+ Ok ( vm
163
+ . ctx
164
+ . new_tuple ( vec ! [ vm. ctx. new_int( div) , vm. ctx. new_int( modulo) ] ) )
146
165
}
147
166
}
148
167
@@ -269,13 +288,18 @@ impl PyInt {
269
288
#[ pymethod( name = "__floordiv__" ) ]
270
289
fn floordiv ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
271
290
if objtype:: isinstance ( & other, & vm. ctx . int_type ( ) ) {
272
- let v2 = get_value ( & other) ;
273
- if * v2 != BigInt :: zero ( ) {
274
- let modulo = ( & self . value % v2 + v2) % v2;
275
- Ok ( vm. ctx . new_int ( ( & self . value - modulo) / v2) )
276
- } else {
277
- Err ( vm. new_zero_division_error ( "integer floordiv by zero" . to_string ( ) ) )
278
- }
291
+ let other = other. payload :: < PyInt > ( ) . unwrap ( ) ;
292
+ inner_floordiv ( self , & other, & vm)
293
+ } else {
294
+ Ok ( vm. ctx . not_implemented ( ) )
295
+ }
296
+ }
297
+
298
+ #[ pymethod( name = "__rfloordiv__" ) ]
299
+ fn rfloordiv ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
300
+ if objtype:: isinstance ( & other, & vm. ctx . int_type ( ) ) {
301
+ let other = other. payload :: < PyInt > ( ) . unwrap ( ) ;
302
+ inner_floordiv ( & other, self , & vm)
279
303
} else {
280
304
Ok ( vm. ctx . not_implemented ( ) )
281
305
}
@@ -397,15 +421,18 @@ impl PyInt {
397
421
#[ pymethod( name = "__divmod__" ) ]
398
422
fn divmod ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
399
423
if objtype:: isinstance ( & other, & vm. ctx . int_type ( ) ) {
400
- let v2 = get_value ( & other) ;
401
- if * v2 != BigInt :: zero ( ) {
402
- let ( r1, r2) = self . value . div_rem ( v2) ;
403
- Ok ( vm
404
- . ctx
405
- . new_tuple ( vec ! [ vm. ctx. new_int( r1) , vm. ctx. new_int( r2) ] ) )
406
- } else {
407
- Err ( vm. new_zero_division_error ( "integer divmod by zero" . to_string ( ) ) )
408
- }
424
+ let other = other. payload :: < PyInt > ( ) . unwrap ( ) ;
425
+ inner_divmod ( self , & other, vm)
426
+ } else {
427
+ Ok ( vm. ctx . not_implemented ( ) )
428
+ }
429
+ }
430
+
431
+ #[ pymethod( name = "__rdivmod__" ) ]
432
+ fn rdivmod ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
433
+ if objtype:: isinstance ( & other, & vm. ctx . int_type ( ) ) {
434
+ let other = other. payload :: < PyInt > ( ) . unwrap ( ) ;
435
+ inner_divmod ( & other, self , vm)
409
436
} else {
410
437
Ok ( vm. ctx . not_implemented ( ) )
411
438
}
0 commit comments