Merge pull request #600 from adrian17/as_ratio

Add float.as_integer_ratio()
This commit is contained in:
Windel Bouwman
2019-03-05 07:22:38 +01:00
committed by GitHub
4 changed files with 58 additions and 0 deletions

View File

@@ -2,12 +2,14 @@ use super::objbytes;
use super::objint;
use super::objstr;
use super::objtype;
use crate::function::PyRef;
use crate::pyobject::{
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
TypeProtocol,
};
use crate::vm::VirtualMachine;
use num_bigint::ToBigInt;
use num_rational::Ratio;
use num_traits::ToPrimitive;
#[derive(Debug, Copy, Clone, PartialEq)]
@@ -27,6 +29,25 @@ impl From<f64> for PyFloat {
}
}
impl PyFloat {
fn as_integer_ratio(zelf: PyRef<Self>, vm: &mut VirtualMachine) -> PyResult {
let value = zelf.value;
if value.is_infinite() {
return Err(
vm.new_overflow_error("cannot convert Infinity to integer ratio".to_string())
);
}
if value.is_nan() {
return Err(vm.new_value_error("cannot convert NaN to integer ratio".to_string()));
}
let ratio = Ratio::from_float(value).unwrap();
let numer = vm.ctx.new_int(ratio.numer().clone());
let denom = vm.ctx.new_int(ratio.denom().clone());
Ok(vm.ctx.new_tuple(vec![numer, denom]))
}
}
fn float_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(float, Some(vm.ctx.float_type()))]);
let v = get_value(float);
@@ -494,4 +515,9 @@ pub fn init(context: &PyContext) {
"is_integer",
context.new_rustfunc(float_is_integer),
);
context.set_attr(
&float_type,
"as_integer_ratio",
context.new_rustfunc(PyFloat::as_integer_ratio),
);
}