From fe3a728e1f27dbb92bcc7ee1c31bfceebea9dea7 Mon Sep 17 00:00:00 2001 From: oshaboy Date: Tue, 24 Dec 2024 10:56:47 +0200 Subject: [PATCH 1/5] Encode Functions --- src/float.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/src/float.rs b/src/float.rs index 4124e92..b14bff1 100644 --- a/src/float.rs +++ b/src/float.rs @@ -796,6 +796,8 @@ pub trait FloatCore: Num + NumCast + Neg + PartialOrd + Copy { /// check(f64::NEG_INFINITY, 1 << 52, 972, -1); /// ``` fn integer_decode(self) -> (u64, i16, i8); + fn integer_encode(m: u64, e: i16, s: i8) -> Self; + fn nan_from_payload(p: u64) -> Self; } impl FloatCore for f32 { @@ -814,7 +816,14 @@ impl FloatCore for f32 { fn integer_decode(self) -> (u64, i16, i8) { integer_decode_f32(self) } - + #[inline] + fn integer_encode(mantissa: u64, exp: i16, sign: i8) -> f32 { + integer_encode_f32(mantissa, exp, sign) + } + #[inline] + fn nan_from_payload(payload: u64) -> f32 { + nan_from_payload_f32(payload) + } forward! { Self::is_nan(self) -> bool; Self::is_infinite(self) -> bool; @@ -876,7 +885,14 @@ impl FloatCore for f64 { fn integer_decode(self) -> (u64, i16, i8) { integer_decode_f64(self) } - + #[inline] + fn integer_encode(mantissa: u64, exp: i16, sign: i8) -> f64 { + integer_encode_f64(mantissa, exp, sign) + } + #[inline] + fn nan_from_payload(payload: u64) -> f64 { + nan_from_payload_f64(payload) + } forward! { Self::is_nan(self) -> bool; Self::is_infinite(self) -> bool; @@ -1936,7 +1952,7 @@ macro_rules! float_impl_std { fn integer_decode(self) -> (u64, i16, i8) { $decode(self) } - + forward! { Self::is_nan(self) -> bool; Self::is_infinite(self) -> bool; @@ -2059,7 +2075,20 @@ fn integer_decode_f32(f: f32) -> (u64, i16, i8) { exponent -= 127 + 23; (mantissa as u64, exponent, sign) } - +fn integer_encode_f32(mantissa: u64, exp: i16, sign: i8) -> f32 { + let sign_mask: u32 = if sign < 0 { 0x8000_0000 } else { 0 }; + if exp <= (-127 + 23) { + let mantissa_mask: u32 = ((mantissa as u32) & 0x7fffff) >> 1; + // Exponent bias + mantissa shift + f32::from_bits(sign_mask|mantissa_mask) + } else { + let exp_ = exp.max(128+23); + let exponent_mask: u32 = ((exp_ + 127 - 23) as u32) << 23; + let mantissa_mask: u32 = (mantissa as u32) & 0x7fffff; + // Exponent bias + mantissa shift + f32::from_bits(sign_mask|exponent_mask|mantissa_mask) + } +} fn integer_decode_f64(f: f64) -> (u64, i16, i8) { let bits: u64 = f.to_bits(); let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; @@ -2073,7 +2102,26 @@ fn integer_decode_f64(f: f64) -> (u64, i16, i8) { exponent -= 1023 + 52; (mantissa, exponent, sign) } - +fn integer_encode_f64(mantissa: u64, exp: i16, sign: i8) -> f64 { + let sign_mask: u64 = if sign < 0 { 0x8000_0000_0000_0000 } else { 0 }; + if exp <= (-1023 + 52) { + let mantissa_mask: u64 = (mantissa & 0xfffffffffffff) >> 1; + // Exponent bias + mantissa shift + f64::from_bits(sign_mask|mantissa_mask) + } else { + let exp_ = exp.max(1024 + 52); + let exponent_mask: u64 = ((exp_ + 1023 - 52) as u64) << 52; + let mantissa_mask: u64 = mantissa & 0xfffffffffffff; + // Exponent bias + mantissa shift + f64::from_bits(sign_mask|exponent_mask|mantissa_mask) + } +} +fn nan_from_payload_f64(payload: u64) -> f64 { + integer_encode_f64(payload, 1024+52, 0) +} +fn nan_from_payload_f32(payload: u64) -> f32 { + integer_encode_f32(payload, 128+52, 0) +} #[cfg(feature = "std")] float_impl_std!(f32 integer_decode_f32); #[cfg(feature = "std")] From f622a43a3166de356ed5609c894e1fe4adac0567 Mon Sep 17 00:00:00 2001 From: oshaboy Date: Tue, 24 Dec 2024 11:12:17 +0200 Subject: [PATCH 2/5] Update float.rs --- src/float.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/float.rs b/src/float.rs index b14bff1..adad759 100644 --- a/src/float.rs +++ b/src/float.rs @@ -1951,8 +1951,7 @@ macro_rules! float_impl_std { #[inline] fn integer_decode(self) -> (u64, i16, i8) { $decode(self) - } - + } forward! { Self::is_nan(self) -> bool; Self::is_infinite(self) -> bool; From 72defacc4af0eda3543c2212c871de4021913e61 Mon Sep 17 00:00:00 2001 From: oshaboy Date: Tue, 24 Dec 2024 11:12:58 +0200 Subject: [PATCH 3/5] Update float.rs --- src/float.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/float.rs b/src/float.rs index adad759..3562048 100644 --- a/src/float.rs +++ b/src/float.rs @@ -1951,7 +1951,8 @@ macro_rules! float_impl_std { #[inline] fn integer_decode(self) -> (u64, i16, i8) { $decode(self) - } + } + forward! { Self::is_nan(self) -> bool; Self::is_infinite(self) -> bool; From 2a8aef578d89bea7e18c2f7ea3aff7828cc78542 Mon Sep 17 00:00:00 2001 From: oshaboy Date: Tue, 24 Dec 2024 11:13:39 +0200 Subject: [PATCH 4/5] Update float.rs --- src/float.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/float.rs b/src/float.rs index 3562048..99c2b35 100644 --- a/src/float.rs +++ b/src/float.rs @@ -1952,7 +1952,7 @@ macro_rules! float_impl_std { fn integer_decode(self) -> (u64, i16, i8) { $decode(self) } - + forward! { Self::is_nan(self) -> bool; Self::is_infinite(self) -> bool; From eb59c059bf75ef1888cd71ff0a0b95d440563698 Mon Sep 17 00:00:00 2001 From: oshaboy Date: Tue, 24 Dec 2024 11:15:03 +0200 Subject: [PATCH 5/5] Update float.rs --- src/float.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/float.rs b/src/float.rs index 99c2b35..8c9c7ce 100644 --- a/src/float.rs +++ b/src/float.rs @@ -816,14 +816,17 @@ impl FloatCore for f32 { fn integer_decode(self) -> (u64, i16, i8) { integer_decode_f32(self) } + #[inline] fn integer_encode(mantissa: u64, exp: i16, sign: i8) -> f32 { integer_encode_f32(mantissa, exp, sign) } + #[inline] fn nan_from_payload(payload: u64) -> f32 { nan_from_payload_f32(payload) } + forward! { Self::is_nan(self) -> bool; Self::is_infinite(self) -> bool; @@ -885,14 +888,17 @@ impl FloatCore for f64 { fn integer_decode(self) -> (u64, i16, i8) { integer_decode_f64(self) } + #[inline] fn integer_encode(mantissa: u64, exp: i16, sign: i8) -> f64 { integer_encode_f64(mantissa, exp, sign) } + #[inline] fn nan_from_payload(payload: u64) -> f64 { nan_from_payload_f64(payload) } + forward! { Self::is_nan(self) -> bool; Self::is_infinite(self) -> bool; @@ -2075,6 +2081,7 @@ fn integer_decode_f32(f: f32) -> (u64, i16, i8) { exponent -= 127 + 23; (mantissa as u64, exponent, sign) } + fn integer_encode_f32(mantissa: u64, exp: i16, sign: i8) -> f32 { let sign_mask: u32 = if sign < 0 { 0x8000_0000 } else { 0 }; if exp <= (-127 + 23) { @@ -2102,6 +2109,7 @@ fn integer_decode_f64(f: f64) -> (u64, i16, i8) { exponent -= 1023 + 52; (mantissa, exponent, sign) } + fn integer_encode_f64(mantissa: u64, exp: i16, sign: i8) -> f64 { let sign_mask: u64 = if sign < 0 { 0x8000_0000_0000_0000 } else { 0 }; if exp <= (-1023 + 52) {