nonstdfloat 0.1.1

Floating point calculations for strafe
Documentation
use std::{
    fmt::{Debug, Display, Formatter, Result as FmtResult},
    ops::{Add, AddAssign, Mul},
};

use bitvec::{order::Lsb0, prelude::*, vec::BitVec};
use num_traits::{FromPrimitive, One, ToPrimitive, Zero};

use crate::{signed::SignedIntegerExtendable, unsigned::UnsignedIntegerExtendable};

pub const BASE: usize = 2;

fn base() -> UnsignedIntegerExtendable {
    UnsignedIntegerExtendable::from_usize(BASE).unwrap()
}

#[derive(Clone, Debug)]
pub struct FloatExtendable {
    sign: bool,
    significand: UnsignedIntegerExtendable,
    exponent: SignedIntegerExtendable,
    precision_lock: usize,
}

impl FloatExtendable {
    pub fn new() -> Self {
        Self {
            sign: false,
            significand: UnsignedIntegerExtendable::zero(),
            exponent: SignedIntegerExtendable::zero(),
            precision_lock: 0,
        }
    }

    pub fn precision_lock(&mut self, lock_bit: usize) {
        self.precision_lock = lock_bit;
    }

    pub fn precision_unlock(&mut self) {
        self.precision_lock = 0;
    }

    // pub fn normalize(&mut self) {
    //     self
    // }

    // pub fn precision_lock_decimal(&mut self, digit: usize) {
    //
    // }
    //
    // fn sign(&self) -> bool {
    //     self.sign
    // }
    //
    // fn sign_mut(&mut self) -> &mut bool {
    //     &mut self.sign
    // }
    //
    // fn significand(&self) -> UnsignedIntegerExtendable {
    //     self.significand.clone()
    // }
    //
    // fn significand_mut(&mut self) -> &mut UnsignedIntegerExtendable {
    //     &mut self.significand
    // }
    //
    // fn exponent(&self) -> SignedIntegerExtendable {
    //     self.exponent.clone()
    // }
    //
    // fn exponent_mut(&mut self) -> &mut SignedIntegerExtendable {
    //     &mut self.exponent
    // }
    //
    // fn digits(&self) -> UnsignedIntegerExtendable {
    //     UnsignedIntegerExtendable::from_usize(self.significand.0.len()).unwrap()
    // }
    //
    // fn decimal_digits(&self) -> UnsignedIntegerExtendable {
    //     self.digits() * base().to_signed().log10().to_unsigned()
    // }

    fn exponent_bias(&self) -> UnsignedIntegerExtendable {
        base()
            .to_signed()
            .pow(self.exponent.0.len() - 1)
            .to_unsigned()
            - UnsignedIntegerExtendable::one()
    }

    // fn emin(&self) -> UnsignedIntegerExtendable {
    //     UnsignedIntegerExtendable::one() - self.emax()
    // }
    //
    // fn emax(&self) -> UnsignedIntegerExtendable {
    //     self.exponent_bias()
    // }
    //
    // fn decimal_emin(&self) -> UnsignedIntegerExtendable {
    //     UnsignedIntegerExtendable::one() - self.decimal_emax()
    // }
    //
    // fn decimal_emax(&self) -> UnsignedIntegerExtendable {
    //     self.emax() * base().to_signed().log10().to_unsigned()
    // }
    //
    // fn quiet_nan(significand_size: usize, exponent_size: usize) -> Self {
    //     let mut ret = Self::new(significand_size, exponent_size);
    //     ret.exponent_mut().0.iter_mut().for_each(|mut b| *b = true);
    //     ret
    // }
}

impl Display for FloatExtendable {
    fn fmt(&self, _f: &mut Formatter) -> FmtResult {
        unimplemented!()
    }
}

impl Zero for FloatExtendable {
    fn zero() -> Self {
        Self {
            sign: false,
            significand: UnsignedIntegerExtendable::zero(),
            exponent: SignedIntegerExtendable::zero(),
            precision_lock: 0,
        }
    }

    fn set_zero(&mut self) {
        *self = Self::zero();
    }

    fn is_zero(&self) -> bool {
        self.significand.is_zero() && self.exponent.is_zero()
    }
}

impl One for FloatExtendable {
    fn one() -> Self {
        Self {
            sign: false,
            significand: UnsignedIntegerExtendable::one(),
            exponent: SignedIntegerExtendable::zero(),
            precision_lock: 0,
        }
    }

    fn set_one(&mut self) {
        *self = Self::one();
    }

    // fn is_one(&self) -> bool where
    //     Self: PartialEq, {
    //     unimplemented!()
    // }
}

impl ToPrimitive for FloatExtendable {
    fn to_i64(&self) -> Option<i64> {
        unimplemented!()
    }

    fn to_u64(&self) -> Option<u64> {
        unimplemented!()
    }
}

impl FromPrimitive for FloatExtendable {
    fn from_i64(_n: i64) -> Option<Self> {
        unimplemented!()
    }

    fn from_u64(n: u64) -> Option<Self> {
        Self::from_f64(n.to_f64().unwrap())
    }

    fn from_f64(n: f64) -> Option<Self> {
        n.to_f64().and_then(|n| {
            let mut bits = BitVec::new();
            bits.extend_from_slice(n.to_le_bytes().bits::<Lsb0>());
            bits.reverse();
            Some(Self {
                sign: *bits.first().unwrap(),
                significand: UnsignedIntegerExtendable(BitVec::from_bitslice(
                    &bits[(1 + 1)..(11 + 1)],
                )),
                exponent: SignedIntegerExtendable(BitVec::from_bitslice(&bits[(11 + 1)..])),
                precision_lock: 0,
            })
        })
    }
}

impl Add for FloatExtendable {
    type Output = Self;

    fn add(mut self, mut _rhs: Self) -> Self::Output {
        // if self.exponent.clone() != rhs.exponent.clone() {
        //     let new_exp = self.exponent.clone().max(rhs.exponent.clone());
        //
        //     self.exponent.0.insert(1, true);
        //     while self.exponent.clone() < new_exp {
        //         self.significand.0.insert(0, false);
        //         self.exponent -= SignedIntegerExtendable::one();
        //     }
        //
        //     rhs.exponent.0.insert(1, true);
        //     while rhs.exponent.clone() < new_exp {
        //         rhs.significand.0.insert(0, false);
        //         rhs.exponent -= SignedIntegerExtendable::one();
        //     }
        // }
        //
        // self.significand += rhs.significand;

        Self::zero()
    }
}

impl AddAssign for FloatExtendable {
    fn add_assign(&mut self, rhs: Self) {
        *self = self.clone() + rhs;
    }
}

impl Mul for FloatExtendable {
    type Output = Self;

    fn mul(self, _rhs: Self) -> Self::Output {
        // if self.significand.is_zero() || rhs.significand.is_zero() {
        //     Self::zero()
        // } else {
        //     let ret = Self {
        //         sign: self.sign ^ rhs.sign,
        //         significand: self.clone().significand * rhs.significand,
        //         // TODO: Which bias do we use?
        //         exponent: self.clone().exponent + rhs.exponent - self.exponent_bias().to_signed(),
        //         precision_lock: match (self.precision_lock, rhs.precision_lock) {
        //             (0, 0) => 0,
        //             (0, p) | (p, 0) => p,
        //             (p1, p2) => p1.min(p2),
        //         },
        //     };
        //     // Normalize
        //     // Check under/over flow
        //         // if self - rhs - bias >= emax: inf
        //         // if self - rhs - bias <= emin: 0
        //     Self::zero()
        // }
        unimplemented!()
    }
}

// #[test]
// fn floating() {
//     let x = FloatExtendable::new();
//     let y = FloatExtendable::from_f64(-12.0).unwrap();
// }