diff --git a/README.md b/README.md index 1757ef1..c72164a 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,12 @@ Various conversion methods are available: * Bug fix: rounding could produce bad output for [`Binary`], [`Octal`], [`LowerHex`] and [`UpperHex`]. + * The following methods are now `const` functions: [`abs`], + [`wrapping_abs`], [`overflowing_abs`]. + +[`abs`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.abs +[`overflowing_abs`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.overflowing_abs +[`wrapping_abs`]: https://docs.rs/fixed/0.4.3/fixed/struct.FixedI32.html#method.wrapping_abs ### Version 0.4.3 news (2019-08-20) diff --git a/RELEASES.md b/RELEASES.md index d9583a6..759ce0d 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -10,6 +10,8 @@ Version 0.4.4 (unreleased) * Bug fix: rounding could produce bad output for `Binary`, `Octal`, `LowerHex` and `UpperHex`. + * The following methods are now `const` functions: `abs`, + `wrapping_abs`, `overflowing_abs`. Version 0.4.3 (2019-08-20) ========================== diff --git a/src/lib.rs b/src/lib.rs index 66f7a2b..0055453 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -244,6 +244,7 @@ mod wrapping; use crate::{ arith::MulDivDir, from_str::FromStrRadix, + helpers::IntHelper, traits::{FromFixed, ToFixed}, types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8}, }; diff --git a/src/macros_no_frac.rs b/src/macros_no_frac.rs index 1c7661f..06614ea 100644 --- a/src/macros_no_frac.rs +++ b/src/macros_no_frac.rs @@ -192,7 +192,7 @@ assert_eq!(Fix::from_bits(bits).rotate_right(3), Fix::from_bits(rot)); if_signed! { $Signedness; - delegate!( + comment!( "Returns the absolute value. # Examples @@ -206,8 +206,16 @@ assert_eq!(five.abs(), five); assert_eq!(minus_five.abs(), five); ``` "; - $Fixed => fn abs(self) + #[inline] + pub const fn abs(self) -> $Fixed { + Self::from_bits((self.to_bits() ^ self.repeat_sign()) - self.repeat_sign()) + } ); + + #[inline] + const fn repeat_sign(self) -> $Inner { + self.to_bits() >> (<$Inner>::NBITS - 1) + } } comment!( @@ -777,7 +785,7 @@ assert_eq!((Fix::from_num(4)).wrapping_shr(3 + ", $s_nbits, "), Fix::from_num(1) if_signed! { $Signedness; - delegate!( + comment!( "Wrapping absolute value. Returns the absolute value, wrapping on overflow. Overflow can only occur when trying to find the absolute value of the minimum value. @@ -791,7 +799,12 @@ assert_eq!(Fix::from_num(-5).wrapping_abs(), Fix::from_num(5)); assert_eq!(Fix::min_value().wrapping_abs(), Fix::min_value()); ``` "; - $Fixed => fn wrapping_abs(self) + #[inline] + pub const fn wrapping_abs(self) -> $Fixed { + Self::from_bits( + (self.to_bits() ^ self.repeat_sign()).wrapping_sub(self.repeat_sign()), + ) + } ); } @@ -1087,8 +1100,9 @@ assert_eq!(Fix::min_value().overflowing_abs(), (Fix::min_value(), true)); [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html "; #[inline] - pub fn overflowing_abs(self) -> ($Fixed, bool) { - let (ans, o) = self.to_bits().overflowing_abs(); + pub const fn overflowing_abs(self) -> ($Fixed, bool) { + let (ans, o) = (self.to_bits() ^ self.repeat_sign()) + .overflowing_sub(self.repeat_sign()); (Self::from_bits(ans), o) } );