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;
}
fn exponent_bias(&self) -> UnsignedIntegerExtendable {
base()
.to_signed()
.pow(self.exponent.0.len() - 1)
.to_unsigned()
- UnsignedIntegerExtendable::one()
}
}
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();
}
}
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 {
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 {
unimplemented!()
}
}