From 577f0332f2744ee4dc0c4f2d5ca1a43c74d9d62e Mon Sep 17 00:00:00 2001
From: Shaopeng Wang <spxwang@gmail.com>
Date: Wed, 11 Mar 2020 15:26:17 +1300
Subject: [PATCH] Impl saturating_abs for Fixed128. (#116)

---
 utilities/src/fixed_128.rs | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/utilities/src/fixed_128.rs b/utilities/src/fixed_128.rs
index 8623622..601d5da 100644
--- a/utilities/src/fixed_128.rs
+++ b/utilities/src/fixed_128.rs
@@ -172,6 +172,19 @@ impl Fixed128 {
 	pub fn is_zero(&self) -> bool {
 		self.0 == 0
 	}
+
+	/// Saturating absolute value. Returning MAX if `parts` == i128::MIN instead of overflowing.
+	pub fn saturating_abs(&self) -> Self {
+		if self.0 == i128::min_value() {
+			return Fixed128::max_value();
+		}
+
+		if self.0.is_negative() {
+			Fixed128::from_parts(self.0 * -1)
+		} else {
+			*self
+		}
+	}
 }
 
 impl Saturating for Fixed128 {
@@ -530,4 +543,14 @@ mod tests {
 		let deserialized: Fixed128 = serde_json::from_str(&serialized).unwrap();
 		assert_eq!(deserialized, minus_two_point_five);
 	}
+
+	#[test]
+	fn saturating_abs_should_work() {
+		// normal
+		assert_eq!(Fixed128::from_parts(1).saturating_abs(), Fixed128::from_parts(1));
+		assert_eq!(Fixed128::from_parts(-1).saturating_abs(), Fixed128::from_parts(1));
+
+		// saturating
+		assert_eq!(Fixed128::min_value().saturating_abs(), Fixed128::max_value());
+	}
 }
-- 
GitLab