From 5c13b81ac8525a004abd175cf229f95545200358 Mon Sep 17 00:00:00 2001 From: 0xgleb Date: Mon, 16 Jun 2025 20:18:22 +0400 Subject: [PATCH 1/2] add frac and floor functions --- crates/float/src/lib.rs | 102 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/crates/float/src/lib.rs b/crates/float/src/lib.rs index 6ba7688f..e7f8fe97 100644 --- a/crates/float/src/lib.rs +++ b/crates/float/src/lib.rs @@ -313,6 +313,28 @@ impl Div for Float { } } +impl Float { + pub fn frac(self) -> Result { + let Float(a) = self; + let calldata = DecimalFloat::fracCall { a }.abi_encode(); + + execute_call(Bytes::from(calldata), |output| { + let decoded = DecimalFloat::fracCall::abi_decode_returns(output.as_ref())?; + Ok(Float(decoded)) + }) + } + + pub fn floor(self) -> Result { + let Float(a) = self; + let calldata = DecimalFloat::floorCall { a }.abi_encode(); + + execute_call(Bytes::from(calldata), |output| { + let decoded = DecimalFloat::floorCall::abi_decode_returns(output.as_ref())?; + Ok(Float(decoded)) + }) + } +} + #[cfg(test)] mod tests { use super::*; @@ -667,4 +689,84 @@ mod tests { FloatError::DecimalFloat(DecimalFloatErrors::ExponentOverflow(_)) )); } + + #[test] + fn test_frac_and_floor_integers() { + let int_float = Float::parse("12345".to_string()).unwrap(); + let floor = int_float.floor().unwrap(); + let frac = int_float.frac().unwrap(); + let zero = Float::parse("0".to_string()).unwrap(); + + assert!(int_float.eq(floor).unwrap()); + assert!(frac.eq(zero).unwrap()); + + let int_float = Float::parse("-98765".to_string()).unwrap(); + let floor = int_float.floor().unwrap(); + let frac = int_float.frac().unwrap(); + let zero = Float::parse("0".to_string()).unwrap(); + + assert!(int_float.eq(floor).unwrap()); + assert!(frac.eq(zero).unwrap()); + + let recombined = (floor + frac).unwrap(); + assert!(int_float.eq(recombined).unwrap()); + } + + #[test] + fn test_frac_and_floor_floats() { + let float = Float::parse("12345.6789".to_string()).unwrap(); + let floor = float.floor().unwrap(); + let frac = float.frac().unwrap(); + + let expected_floor = Float::parse("12345".to_string()).unwrap(); + let expected_frac = Float::parse("0.6789".to_string()).unwrap(); + + assert!(floor.eq(expected_floor).unwrap()); + assert!(frac.eq(expected_frac).unwrap()); + } + + proptest! { + #[test] + fn test_frac_floor_properties(float in arb_float()) { + let floor = float.floor().unwrap(); + let frac = float.frac().unwrap(); + + let zero = Float::parse("0".to_string()).unwrap(); + + prop_assert!( + floor.frac().unwrap().eq(zero).unwrap(), + "floor.frac() is not zero: {}", + floor.show_unpacked().unwrap() + ); + + prop_assert!( + frac.floor().unwrap().eq(zero).unwrap(), + "frac.floor() is not zero: {}", + frac.show_unpacked().unwrap() + ); + + let recombined = (floor + frac).unwrap(); + prop_assert!( + float.eq(recombined).unwrap(), + "original: {}, floor: {}, frac: {}, recombined: {}", + float.show_unpacked().unwrap(), + floor.show_unpacked().unwrap(), + frac.show_unpacked().unwrap(), + recombined.show_unpacked().unwrap() + ); + + let one = Float::parse("1".to_string()).unwrap(); + let neg_one = one.minus().unwrap(); + prop_assert!( + frac.lt(one).unwrap(), + "frac not < 1: {}", + frac.show_unpacked().unwrap() + ); + prop_assert!( + frac.gt(neg_one).unwrap(), + "frac not > -1: {}", + frac.show_unpacked().unwrap() + ); + } + } } From 24ee32d97e14001491df1186b94491ff189b9e2a Mon Sep 17 00:00:00 2001 From: 0xgleb Date: Thu, 19 Jun 2025 14:38:24 +0400 Subject: [PATCH 2/2] fix merge duplicate --- crates/float/src/lib.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/crates/float/src/lib.rs b/crates/float/src/lib.rs index 70a8ee5a..051f3f94 100644 --- a/crates/float/src/lib.rs +++ b/crates/float/src/lib.rs @@ -232,16 +232,6 @@ impl Float { }) } - pub fn minus(self) -> Result { - let Float(a) = self; - let calldata = DecimalFloat::minusCall { a }.abi_encode(); - - execute_call(Bytes::from(calldata), |output| { - let decoded = DecimalFloat::minusCall::abi_decode_returns(output.as_ref())?; - Ok(Float(decoded)) - }) - } - pub fn inv(self) -> Result { let Float(a) = self; let calldata = DecimalFloat::invCall { a }.abi_encode(); @@ -817,7 +807,7 @@ mod tests { ); let one = Float::parse("1".to_string()).unwrap(); - let neg_one = one.minus().unwrap(); + let neg_one = one.neg().unwrap(); prop_assert!( frac.lt(one).unwrap(), "frac not < 1: {}",