use crate::InnerFloat::{Finite, Zero};
use crate::{Float, significand_bits};
use malachite_base::num::basic::traits::Zero as ZeroTrait;
use malachite_base::num::conversion::traits::ConvertibleFrom;
use malachite_nz::integer::Integer;
use malachite_q::Rational;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct RationalFromFloatError;
impl TryFrom<Float> for Rational {
type Error = RationalFromFloatError;
fn try_from(x: Float) -> Result<Self, Self::Error> {
match x {
float_either_zero!() => Ok(Self::ZERO),
Float(Finite {
sign,
exponent,
significand,
..
}) => {
let bits = significand_bits(&significand);
Ok(Self::from(Integer::from_sign_and_abs(sign, significand))
<< (i128::from(exponent) - i128::from(bits)))
}
_ => Err(RationalFromFloatError),
}
}
}
impl TryFrom<&Float> for Rational {
type Error = RationalFromFloatError;
fn try_from(x: &Float) -> Result<Self, Self::Error> {
match x {
float_either_zero!() => Ok(Self::ZERO),
Float(Finite {
sign,
exponent,
significand,
..
}) => {
let bits = significand_bits(significand);
Ok(
Self::from(Integer::from_sign_and_abs_ref(*sign, significand))
<< (i128::from(*exponent) - i128::from(bits)),
)
}
_ => Err(RationalFromFloatError),
}
}
}
impl ConvertibleFrom<&Float> for Rational {
#[inline]
fn convertible_from(x: &Float) -> bool {
x.is_finite()
}
}