@@ -139,10 +139,29 @@ fn inner_pow(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
139139}
140140
141141fn 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 {
143145 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 ( ) ) )
144152 } 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) ] ) )
146165 }
147166}
148167
@@ -269,13 +288,18 @@ impl PyInt {
269288 #[ pymethod( name = "__floordiv__" ) ]
270289 fn floordiv ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
271290 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)
279303 } else {
280304 Ok ( vm. ctx . not_implemented ( ) )
281305 }
@@ -397,15 +421,18 @@ impl PyInt {
397421 #[ pymethod( name = "__divmod__" ) ]
398422 fn divmod ( & self , other : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
399423 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)
409436 } else {
410437 Ok ( vm. ctx . not_implemented ( ) )
411438 }
0 commit comments