use rug::Integer;
use std::cmp::Ordering;
use crate::{rfloat::RFloat, Real};
use super::FloatContext;
#[derive(Clone, Debug, Default)]
pub struct Exceptions {
pub invalid: bool,
pub divzero: bool,
pub inexact: bool,
pub carry: bool,
}
impl Exceptions {
pub fn new() -> Self {
Self {
invalid: false,
divzero: false,
inexact: false,
carry: false,
}
}
}
#[derive(Debug, Clone)]
pub struct Float {
pub(crate) num: RFloat,
pub(crate) flags: Exceptions,
pub(crate) ctx: FloatContext,
}
impl Float {
pub fn flags(&self) -> &Exceptions {
&self.flags
}
pub fn ctx(&self) -> &FloatContext {
&self.ctx
}
}
impl Real for Float {
fn radix() -> usize {
2
}
fn sign(&self) -> Option<bool> {
self.num.sign()
}
fn exp(&self) -> Option<isize> {
self.num.exp()
}
fn e(&self) -> Option<isize> {
self.num.e()
}
fn n(&self) -> Option<isize> {
self.num.n()
}
fn c(&self) -> Option<Integer> {
self.num.c()
}
fn m(&self) -> Option<Integer> {
self.num.m()
}
fn prec(&self) -> Option<usize> {
self.num.prec()
}
fn is_nar(&self) -> bool {
self.num.is_nar()
}
fn is_finite(&self) -> bool {
self.num.is_finite()
}
fn is_infinite(&self) -> bool {
self.num.is_finite()
}
fn is_zero(&self) -> bool {
self.num.is_zero()
}
fn is_negative(&self) -> Option<bool> {
self.num.is_negative()
}
fn is_numerical(&self) -> bool {
self.num.is_numerical()
}
}
impl From<Float> for RFloat {
fn from(value: Float) -> Self {
value.num
}
}
impl From<Float> for rug::Float {
fn from(value: Float) -> Self {
rug::Float::from(value.num)
}
}
impl PartialOrd for Float {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.num.partial_cmp(&other.num)
}
}
impl PartialEq for Float {
fn eq(&self, other: &Self) -> bool {
self.partial_cmp(other) == Some(Ordering::Equal)
}
}