From 031cd6e77182ea80c9452ca9ccc42418747fab69 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Tue, 17 Sep 2024 14:47:14 -0700
Subject: [PATCH] float builder (debug version)

---
 fixed_wide/src/fixed.rs | 73 ++++++++++++++++++++++++++++++++---------
 1 file changed, 57 insertions(+), 16 deletions(-)

diff --git a/fixed_wide/src/fixed.rs b/fixed_wide/src/fixed.rs
index 84667bc..bcee486 100644
--- a/fixed_wide/src/fixed.rs
+++ b/fixed_wide/src/fixed.rs
@@ -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 {
-	( $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>{
 			#[inline]
 			fn into(self)->$output{
-				let mut total=0.0;
-				let bits=self.bits.to_bits();
-				let digits=bits.digits();
-				for (i,digit) in digits[0..N-1].iter().enumerate(){
-					// (i*64-F) as i32 will interpret the highest order bit as a sign bit but whatever
-					total+=(*digit as $output)*(2.0 as $output).powi((i*64-F) as i32);
+				const DIGIT_SHIFT:u32=6;//Log2[64]
+				// SBBB BBBB
+				// 1001 1110 0000 0000
+				let sign=if self.bits.is_negative(){(1 as $unsigned)<<(<$unsigned>::BITS-1)}else{0};
+				println!("sign={sign}");
+				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
-				//assume we are using a number with at least 1 digit...
-				total+=((*digits.last().unwrap() as i64).abs() as $output)*(2.0 as $output).powi(((N-1)*64-F) as i32);
-				if self.bits.is_negative(){
-					total=-total;
-				}
-				total
+				let mant=unmasked_mant&((1 as $unsigned)<<($mantissa_bits-1))-1;
+				println!("mant={mant:#034b}");
+				let bits=sign|exp|mant;
+				println!("bits={bits:#034b}");
+				<$output>::from_bits(bits)
 			}
 		}
 	}
 }
-impl_into_float!(f32);
-impl_into_float!(f64);
+impl_into_float!(f32,u32,8,24);
+impl_into_float!(f64,u64,11,53);
 
 impl<const N:usize,const F:usize> core::fmt::Display for Fixed<N,F>{
 	#[inline]