float builder (debug version)

This commit is contained in:
Quaternions 2024-09-17 14:47:14 -07:00
parent 6dbe96fca2
commit 031cd6e771

View File

@ -138,31 +138,72 @@ impl<const N:usize,const F:usize> std::iter::Sum for Fixed<N,F>{
} }
} }
const fn signed_shift(lhs:u64,rhs:i32)->u64{
if rhs.is_negative(){
lhs>>-rhs
}else{
lhs<<rhs
}
}
macro_rules! impl_into_float { macro_rules! impl_into_float {
( $output: ty ) => { ( $output: ty, $unsigned:ty, $exponent_bits:expr, $mantissa_bits:expr ) => {
impl<const N:usize,const F:usize> Into<$output> for Fixed<N,F>{ impl<const N:usize,const F:usize> Into<$output> for Fixed<N,F>{
#[inline] #[inline]
fn into(self)->$output{ fn into(self)->$output{
let mut total=0.0; const DIGIT_SHIFT:u32=6;//Log2[64]
let bits=self.bits.to_bits(); // SBBB BBBB
let digits=bits.digits(); // 1001 1110 0000 0000
for (i,digit) in digits[0..N-1].iter().enumerate(){ let sign=if self.bits.is_negative(){(1 as $unsigned)<<(<$unsigned>::BITS-1)}else{0};
// (i*64-F) as i32 will interpret the highest order bit as a sign bit but whatever println!("sign={sign}");
total+=(*digit as $output)*(2.0 as $output).powi((i*64-F) as i32); let unsigned=self.bits.unsigned_abs();
println!("unsigned={unsigned}");
let most_significant_bit=unsigned.bits();
println!("most_significant_bit={most_significant_bit}");
let exp=if unsigned.is_zero(){
0
}else{
let msb=most_significant_bit as $unsigned;
println!("msb={msb}");
let _127=((1 as $unsigned)<<($exponent_bits-1))-1;
println!("_127={_127}");
let msb_offset=msb+_127-1-F as $unsigned;
println!("msb_offset={msb_offset}");
msb_offset<<($mantissa_bits-1)
};
println!("exp={exp:#034b}");
let digits=unsigned.digits();
println!("digits={digits:?}");
let digit_index=most_significant_bit>>DIGIT_SHIFT;
println!("digit_index={digit_index}");
let digit=digits[digit_index as usize];
println!("digit={digit:#034b}");
//How many bits does the mantissa take from this digit
let take_bits=most_significant_bit-(digit_index<<DIGIT_SHIFT);
println!("take_bits={take_bits}");
let rest_of_mantissa=$mantissa_bits as i32-(take_bits as i32);
println!("rest_of_mantissa={rest_of_mantissa}");
let mut unmasked_mant=signed_shift(digit,rest_of_mantissa) as $unsigned;
println!("umnt={unmasked_mant:#034b}");
if 0<rest_of_mantissa&&digit_index!=0{
//take the next digit down and shove some of its bits onto the bottom of the mantissa
let digit=digits[digit_index as usize-1];
let take_bits=most_significant_bit-((digit_index-1)<<DIGIT_SHIFT);
let rest_of_mantissa=$mantissa_bits as i32-(take_bits as i32);
let unmasked_mant2=signed_shift(digit,rest_of_mantissa) as $unsigned;
println!("unmasked_mant2={unmasked_mant2:#034b}");
unmasked_mant|=unmasked_mant2;
} }
//most significant digit holds the sign bit let mant=unmasked_mant&((1 as $unsigned)<<($mantissa_bits-1))-1;
//assume we are using a number with at least 1 digit... println!("mant={mant:#034b}");
total+=((*digits.last().unwrap() as i64).abs() as $output)*(2.0 as $output).powi(((N-1)*64-F) as i32); let bits=sign|exp|mant;
if self.bits.is_negative(){ println!("bits={bits:#034b}");
total=-total; <$output>::from_bits(bits)
}
total
} }
} }
} }
} }
impl_into_float!(f32); impl_into_float!(f32,u32,8,24);
impl_into_float!(f64); impl_into_float!(f64,u64,11,53);
impl<const N:usize,const F:usize> core::fmt::Display for Fixed<N,F>{ impl<const N:usize,const F:usize> core::fmt::Display for Fixed<N,F>{
#[inline] #[inline]