int.__[r]floordiv__ to use BigInt.div_floor

This commit is contained in:
Jeong YunWon
2019-08-11 22:13:04 +09:00
parent e819b9a2e3
commit 039cc12852
2 changed files with 29 additions and 10 deletions

View File

@@ -36,7 +36,13 @@ assert (2).__rsub__(1) == -1
assert (2).__mul__(1) == 2
assert (2).__rmul__(1) == 2
assert (2).__truediv__(1) == 2.0
with assertRaises(ZeroDivisionError):
(2).__truediv__(0)
assert (2).__rtruediv__(1) == 0.5
assert (-2).__floordiv__(3) == -1
with assertRaises(ZeroDivisionError):
(2).__floordiv__(0)
assert (-3).__rfloordiv__(2) == -1
assert (-2).__divmod__(3) == (-1, 1)
with assertRaises(ZeroDivisionError):
(2).__divmod__(0)

View File

@@ -139,10 +139,18 @@ fn inner_pow(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
}
fn inner_mod(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
if int2.value != BigInt::zero() {
Ok(vm.ctx.new_int(&int1.value % &int2.value))
} else {
if int2.value.is_zero() {
Err(vm.new_zero_division_error("integer modulo by zero".to_string()))
} else {
Ok(vm.ctx.new_int(&int1.value % &int2.value))
}
}
fn inner_floordiv(int1: &PyInt, int2: &PyInt, vm: &VirtualMachine) -> PyResult {
if int2.value.is_zero() {
Err(vm.new_zero_division_error("integer division by zero".to_string()))
} else {
Ok(vm.ctx.new_int(int1.value.div_floor(&int2.value)))
}
}
@@ -280,13 +288,18 @@ impl PyInt {
#[pymethod(name = "__floordiv__")]
fn floordiv(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if objtype::isinstance(&other, &vm.ctx.int_type()) {
let v2 = get_value(&other);
if *v2 != BigInt::zero() {
let modulo = (&self.value % v2 + v2) % v2;
Ok(vm.ctx.new_int((&self.value - modulo) / v2))
} else {
Err(vm.new_zero_division_error("integer floordiv by zero".to_string()))
}
let other = other.payload::<PyInt>().unwrap();
inner_floordiv(self, &other, &vm)
} else {
Ok(vm.ctx.not_implemented())
}
}
#[pymethod(name = "__rfloordiv__")]
fn rfloordiv(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if objtype::isinstance(&other, &vm.ctx.int_type()) {
let other = other.payload::<PyInt>().unwrap();
inner_floordiv(&other, self, &vm)
} else {
Ok(vm.ctx.not_implemented())
}