use crate::ext::xmpq;
use crate::ext::xmpz;
use crate::{Assign, Integer, Rational};
use az::CheckedCast;
use core::cmp::Ordering;
use num_traits_crate::cast::{FromPrimitive, ToPrimitive};
use num_traits_crate::identities::{One, Zero};
use num_traits_crate::ops::inv::Inv;
use num_traits_crate::ops::mul_add::{MulAdd, MulAddAssign};
impl Zero for Rational {
#[inline]
fn zero() -> Self {
Rational::new()
}
#[inline]
fn is_zero(&self) -> bool {
self.cmp0() == Ordering::Equal
}
#[inline]
fn set_zero(&mut self) {
xmpq::set_0(self);
}
}
impl One for Rational {
#[inline]
fn one() -> Self {
Rational::from(1u8)
}
#[inline]
fn set_one(&mut self) {
self.assign(1u32);
}
#[inline]
fn is_one(&self) -> bool {
xmpz::is_1(self.numer()) && xmpz::is_1(self.denom())
}
}
impl Inv for Rational {
type Output = Self;
#[inline]
fn inv(self) -> Self::Output {
self.recip()
}
}
impl MulAdd for Rational {
type Output = Rational;
#[inline]
fn mul_add(self, a: Rational, b: Rational) -> Rational {
self * a + b
}
}
impl MulAddAssign for Rational {
#[inline]
fn mul_add_assign(&mut self, a: Rational, b: Rational) {
*self *= a;
*self += b;
}
}
impl MulAdd<&Rational, &Rational> for Rational {
type Output = Rational;
#[inline]
fn mul_add(self, a: &Rational, b: &Rational) -> Rational {
self * a + b
}
}
impl MulAddAssign<&Rational, &Rational> for Rational {
#[inline]
fn mul_add_assign(&mut self, a: &Rational, b: &Rational) {
*self *= a;
*self += b;
}
}
impl ToPrimitive for Rational {
#[inline]
fn to_i64(&self) -> Option<i64> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_u64(&self) -> Option<u64> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_isize(&self) -> Option<isize> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_i8(&self) -> Option<i8> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_i16(&self) -> Option<i16> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_i32(&self) -> Option<i32> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_i128(&self) -> Option<i128> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_usize(&self) -> Option<usize> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_u8(&self) -> Option<u8> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_u16(&self) -> Option<u16> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_u32(&self) -> Option<u32> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_u128(&self) -> Option<u128> {
let trunc = Integer::from(self.trunc_ref());
trunc.checked_cast()
}
#[inline]
fn to_f32(&self) -> Option<f32> {
Some(self.to_f32())
}
#[inline]
fn to_f64(&self) -> Option<f64> {
Some(self.to_f64())
}
}
impl FromPrimitive for Rational {
#[inline]
fn from_i64(n: i64) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_u64(n: u64) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_isize(n: isize) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_i8(n: i8) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_i128(n: i128) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_usize(n: usize) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_u128(n: u128) -> Option<Self> {
Some(n.into())
}
#[inline]
fn from_f32(n: f32) -> Option<Self> {
Self::from_f32(n)
}
#[inline]
fn from_f64(n: f64) -> Option<Self> {
Self::from_f64(n)
}
}