Merge pull request #1585 from adolfogonzalez3/fixing_ceil_floor

Possible fix for math.ceil and math.floor
This commit is contained in:
Noah
2019-12-06 16:30:58 -06:00
committed by GitHub
3 changed files with 21 additions and 3 deletions

View File

@@ -34,6 +34,10 @@ assert math.trunc(2.2) == 2
assert math.ceil(3.3) == 4
assert math.floor(4.4) == 4
assert isinstance(math.trunc(2.2), int)
assert isinstance(math.ceil(3.3), int)
assert isinstance(math.floor(4.4), int)
class A(object):
def __trunc__(self):
return 2

View File

@@ -89,7 +89,7 @@ fn inner_mod(v1: f64, v2: f64, vm: &VirtualMachine) -> PyResult<f64> {
}
}
fn try_to_bigint(value: f64, vm: &VirtualMachine) -> PyResult<BigInt> {
pub fn try_to_bigint(value: f64, vm: &VirtualMachine) -> PyResult<BigInt> {
match value.to_bigint() {
Some(int) => Ok(int),
None => {

View File

@@ -214,19 +214,33 @@ fn math_trunc(value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
try_magic_method("__trunc__", vm, &value)
}
/// Applies ceiling to a float, returning an Integral.
///
/// # Arguments
///
/// * `value` - Either a float or a python object which implements __ceil__
/// * `vm` - Represents the python state.
fn math_ceil(value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if objtype::isinstance(&value, &vm.ctx.float_type()) {
let v = objfloat::get_value(&value);
Ok(vm.ctx.new_float(v.ceil()))
let v = objfloat::try_to_bigint(v.ceil(), vm)?;
Ok(vm.ctx.new_int(v))
} else {
try_magic_method("__ceil__", vm, &value)
}
}
/// Applies floor to a float, returning an Integral.
///
/// # Arguments
///
/// * `value` - Either a float or a python object which implements __ceil__
/// * `vm` - Represents the python state.
fn math_floor(value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
if objtype::isinstance(&value, &vm.ctx.float_type()) {
let v = objfloat::get_value(&value);
Ok(vm.ctx.new_float(v.floor()))
let v = objfloat::try_to_bigint(v.floor(), vm)?;
Ok(vm.ctx.new_int(v))
} else {
try_magic_method("__floor__", vm, &value)
}