diff --git a/crates/float/src/lib.rs b/crates/float/src/lib.rs index 1d1dc972..deaa7776 100644 --- a/crates/float/src/lib.rs +++ b/crates/float/src/lib.rs @@ -231,6 +231,16 @@ impl Float { Ok(decoded) }) } + + pub fn abs(self) -> Result { + let Float(a) = self; + let calldata = DecimalFloat::absCall { a }.abi_encode(); + + execute_call(Bytes::from(calldata), |output| { + let decoded = DecimalFloat::absCall::abi_decode_returns(output.as_ref())?; + Ok(Float(decoded)) + }) + } } impl Add for Float { @@ -496,6 +506,24 @@ mod tests { } } + #[test] + fn test_abs() { + let float = Float::parse("-3613.1324123".to_string()).unwrap(); + let abs = float.abs().unwrap(); + let formatted = abs.format().unwrap(); + assert_eq!(formatted, "3613.1324123"); + + let float = Float::parse("3613.1324123".to_string()).unwrap(); + let abs = float.abs().unwrap(); + let formatted = abs.format().unwrap(); + assert_eq!(formatted, "3613.1324123"); + + let float = Float::parse("0".to_string()).unwrap(); + let abs = float.abs().unwrap(); + let formatted = abs.format().unwrap(); + assert_eq!(formatted, "0"); + } + proptest! { #[test] fn test_mul(a in reasonable_float(), b in reasonable_float()) { @@ -503,6 +531,22 @@ mod tests { } } + proptest! { + #[test] + fn test_abs_no_minus_sign(float in reasonable_float()) { + let abs = float.abs().unwrap(); + let formatted = abs.format().unwrap(); + prop_assert!(!formatted.starts_with("-")); + } + + #[test] + fn test_abs_abs(float in arb_float()) { + let abs = float.abs().unwrap(); + let abs_abs = abs.abs().unwrap(); + prop_assert!(abs.eq(abs_abs).unwrap()); + } + } + proptest! { #[test] fn test_div(a in reasonable_float(), b in reasonable_float()) {