use crate::{
core::{
circuits::boolean::{boolean_value::BooleanValue, byte::Byte},
global_value::value::FieldValue,
},
traits::{FromLeBits, GetBit},
utils::{field::BaseField, used_field::UsedField},
};
use core::panic;
use ff::Field;
#[derive(Debug, Clone)]
pub struct F64 {
pub sign: BooleanValue,
pub exponent: [BooleanValue; 11],
pub mantissa: FieldValue<BaseField>,
}
impl F64 {
#[allow(dead_code)]
pub fn new(
sign: BooleanValue,
exponent: [BooleanValue; 11],
mantissa: FieldValue<BaseField>,
) -> Self {
let bounds = mantissa.bounds();
if bounds.unsigned_min() != BaseField::ZERO
|| bounds.unsigned_max() != BaseField::power_of_two(52) - BaseField::ONE
{
panic!(
"Invalid bounds for the mantissa. Expected (0, 2^52-1) (found {:?} and {:?})",
bounds.unsigned_min(),
bounds.unsigned_max()
);
}
Self {
sign,
exponent,
mantissa,
}
}
pub fn from_le_bytes(bytes: [Byte<BooleanValue>; 8]) -> Self {
let mut bits = bytes
.into_iter()
.flat_map(|byte| byte.get_bits())
.collect::<Vec<BooleanValue>>();
let sign = bits.pop().unwrap();
let exponent = bits
.split_off(52)
.try_into()
.unwrap_or_else(|v: Vec<BooleanValue>| {
panic!("Expected a Vec of length 11 (found {})", v.len())
});
let mantissa = FieldValue::<BaseField>::from_le_bits(bits, false);
Self {
sign,
exponent,
mantissa,
}
}
pub fn to_le_bytes(&self) -> [Byte<BooleanValue>; 8] {
let mut mantissa_bits = (0..52)
.map(|i| self.mantissa.get_bit(i, false))
.collect::<Vec<BooleanValue>>();
mantissa_bits.append(&mut self.exponent.to_vec());
mantissa_bits.push(self.sign);
mantissa_bits
.chunks(8)
.map(|bits| {
Byte::new(
bits.to_vec()
.try_into()
.unwrap_or_else(|v: Vec<BooleanValue>| {
panic!("Expected a Vec of length 8 (found {})", v.len())
}),
)
})
.collect::<Vec<Byte<BooleanValue>>>()
.try_into()
.unwrap_or_else(|v: Vec<Byte<BooleanValue>>| {
panic!("Expected a Vec of length 8 (found {})", v.len())
})
}
}