Skip to content

Commit 039cc12

Browse files
committed
int.__[r]floordiv__ to use BigInt.div_floor
1 parent e819b9a commit 039cc12

2 files changed

Lines changed: 28 additions & 9 deletions

File tree

tests/snippets/ints.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@
3636
assert (2).__mul__(1) == 2
3737
assert (2).__rmul__(1) == 2
3838
assert (2).__truediv__(1) == 2.0
39+
with assertRaises(ZeroDivisionError):
40+
(2).__truediv__(0)
3941
assert (2).__rtruediv__(1) == 0.5
42+
assert (-2).__floordiv__(3) == -1
43+
with assertRaises(ZeroDivisionError):
44+
(2).__floordiv__(0)
45+
assert (-3).__rfloordiv__(2) == -1
4046
assert (-2).__divmod__(3) == (-1, 1)
4147
with assertRaises(ZeroDivisionError):
4248
(2).__divmod__(0)

vm/src/obj/objint.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,18 @@ fn inner_pow(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
139139
}
140140

141141
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 {
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)))
146154
}
147155
}
148156

@@ -280,13 +288,18 @@ impl PyInt {
280288
#[pymethod(name = "__floordiv__")]
281289
fn floordiv(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
282290
if objtype::isinstance(&other, &vm.ctx.int_type()) {
283-
let v2 = get_value(&other);
284-
if *v2 != BigInt::zero() {
285-
let modulo = (&self.value % v2 + v2) % v2;
286-
Ok(vm.ctx.new_int((&self.value - modulo) / v2))
287-
} else {
288-
Err(vm.new_zero_division_error("integer floordiv by zero".to_string()))
289-
}
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)
290303
} else {
291304
Ok(vm.ctx.not_implemented())
292305
}

0 commit comments

Comments
 (0)