use num_traits::Zero;
use rug::Integer;
use std::fmt::Debug;
use crate::rfloat::RFloat;
use crate::util::bitmask;
pub trait Real: Debug {
fn radix() -> usize;
fn sign(&self) -> Option<bool>;
fn exp(&self) -> Option<isize>;
fn e(&self) -> Option<isize>;
fn n(&self) -> Option<isize>;
fn c(&self) -> Option<Integer>;
fn m(&self) -> Option<Integer>;
fn prec(&self) -> Option<usize>;
fn is_nar(&self) -> bool;
fn is_finite(&self) -> bool;
fn is_infinite(&self) -> bool;
fn is_zero(&self) -> bool;
fn is_negative(&self) -> Option<bool>;
fn is_numerical(&self) -> bool;
fn split(&self, n: isize) -> (RFloat, RFloat) {
let s = self.sign().unwrap();
if self.is_zero() {
let high = RFloat::Real(s, 0, Integer::zero());
let low = RFloat::Real(s, 0, Integer::zero());
(high, low)
} else {
let e = self.e().unwrap();
let exp = self.exp().unwrap();
let c = self.c().unwrap();
if n >= e {
let high = RFloat::Real(s, 0, Integer::zero());
let low = RFloat::Real(s, exp, c);
(high, low)
} else if n < exp {
let high = RFloat::Real(s, exp, c);
let low = RFloat::Real(s, 0, Integer::zero());
(high, low)
} else {
let offset = n - (exp - 1);
let mask = bitmask(offset as usize);
let high = RFloat::Real(s, n + 1, c.to_owned() >> offset);
let low = RFloat::Real(s, exp, c & mask);
(high, low)
}
}
}
}