# HG changeset patch # User unC0Rr # Date 1734608448 -3600 # Node ID 624b74443b53ffe8da5238ac8acd9a1bdd47d1bf # Parent db18f1a30b0c787505ca0c6c64021d81239d2b6e Make FPNum use saturating calculations diff -r db18f1a30b0c -r 624b74443b53 rust/fpnum/Cargo.toml --- a/rust/fpnum/Cargo.toml Tue Dec 17 15:44:21 2024 +0100 +++ b/rust/fpnum/Cargo.toml Thu Dec 19 12:40:48 2024 +0100 @@ -2,6 +2,7 @@ name = "fpnum" version = "0.1.0" authors = ["Andrey Korotaev "] -edition = "2018" +edition = "2021" [dependencies] +saturate = "0.1.0" diff -r db18f1a30b0c -r 624b74443b53 rust/fpnum/src/lib.rs --- a/rust/fpnum/src/lib.rs Tue Dec 17 15:44:21 2024 +0100 +++ b/rust/fpnum/src/lib.rs Thu Dec 19 12:40:48 2024 +0100 @@ -1,4 +1,5 @@ -use std::{cmp, ops, ops::Shl}; +use std::{cmp, ops}; +use saturate::SaturatingInto; const POSITIVE_MASK: u64 = 0x0000_0000_0000_0000; const NEGATIVE_MASK: u64 = 0xFFFF_FFFF_FFFF_FFFF; @@ -66,7 +67,7 @@ pub fn sqr(&self) -> Self { Self { sign_mask: 0, - value: ((self.value as u128).pow(2) >> 32) as u64, + value: ((self.value as u128).pow(2) >> 32).saturating_into(), } } @@ -149,7 +150,7 @@ impl PartialOrd for FPNum { #[inline] - fn partial_cmp(&self, rhs: &Self) -> std::option::Option { + fn partial_cmp(&self, rhs: &Self) -> Option { Some(self.cmp(rhs)) } } @@ -204,7 +205,7 @@ fn mul(self, rhs: Self) -> Self { Self { sign_mask: self.sign_mask ^ rhs.sign_mask, - value: ((self.value as u128 * rhs.value as u128) >> 32) as u64, + value: ((self.value as u128 * rhs.value as u128) >> 32).saturating_into(), } } } @@ -216,7 +217,7 @@ fn mul(self, rhs: i32) -> Self { Self { sign_mask: self.sign_mask ^ bool_mask(rhs < 0), - value: self.value * rhs.abs() as u64, + value: (self.value as u128 * rhs.abs() as u128).saturating_into(), } } } @@ -228,7 +229,7 @@ fn div(self, rhs: Self) -> Self { Self { sign_mask: self.sign_mask ^ rhs.sign_mask, - value: (((self.value as u128) << 32) / rhs.value as u128) as u64, + value: (((self.value as u128) << 32) / rhs.value as u128).saturating_into(), } } } @@ -326,7 +327,7 @@ #[inline] pub fn max_norm(&self) -> FPNum { - std::cmp::max(self.x().abs(), self.y().abs()) + cmp::max(self.x().abs(), self.y().abs()) } #[inline] @@ -505,9 +506,10 @@ #[inline] pub fn distance(x: T, y: T) -> FPNum where - T: Into + std::fmt::Debug, + T: Into + std::fmt::Debug, { - let sqr: u128 = (x.into().pow(2) as u128).shl(64) + (y.into().pow(2) as u128).shl(64); + let [x_squared, y_squared] = [x, y].map(|i| (i.into().pow(2) as u128).saturating_mul(2^64)); + let sqr: u128 = x_squared.saturating_add(y_squared); FPNum { sign_mask: POSITIVE_MASK,