From 6f7d295cd82571429064132265f907131841c60f Mon Sep 17 00:00:00 2001 From: Ben Schulz Date: Thu, 11 Apr 2024 17:56:27 +0200 Subject: [PATCH] Fix negation with overflow (#657) * Fix negation with overflow * Extend scope of tests to remove blindness --------- Co-authored-by: Paul Mason --- src/decimal.rs | 2 +- tests/decimal_tests.rs | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/decimal.rs b/src/decimal.rs index 45f5661..20dd9c0 100644 --- a/src/decimal.rs +++ b/src/decimal.rs @@ -1990,7 +1990,7 @@ impl FromPrimitive for Decimal { unsigned = n as u128; flags = 0; } else { - unsigned = -n as u128; + unsigned = n.unsigned_abs(); flags = SIGN_MASK; }; // Check if we overflow diff --git a/tests/decimal_tests.rs b/tests/decimal_tests.rs index 202ef99..03ad08e 100644 --- a/tests/decimal_tests.rs +++ b/tests/decimal_tests.rs @@ -2967,11 +2967,18 @@ fn it_converts_from_i128() { (92233720368547758089, Some("92233720368547758089")), (0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF, Some("79228162514264337593543950335")), (0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, None), + (i128::MIN, None), + (i128::MAX, None), ]; for (value, expected) in tests { - if let Some(expected_value) = expected { - let decimal = Decimal::from_str(expected_value).unwrap(); - assert_eq!(num_traits::FromPrimitive::from_i128(*value), Some(decimal)); + let from_i128 = num_traits::FromPrimitive::from_i128(*value); + + match expected { + Some(expected_value) => { + let decimal = Decimal::from_str(expected_value).unwrap(); + assert_eq!(from_i128, Some(decimal)); + } + None => assert!(from_i128.is_none()), } } } @@ -2983,11 +2990,17 @@ fn it_converts_from_u128() { (0xFFFF_FFFF_FFFF_FFFF, Some("18446744073709551615")), (0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF, Some("79228162514264337593543950335")), (0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF, None), + (u128::MAX, None), ]; for (value, expected) in tests { - if let Some(expected_value) = expected { - let decimal = Decimal::from_str(expected_value).unwrap(); - assert_eq!(num_traits::FromPrimitive::from_u128(*value), Some(decimal)); + let from_u128 = num_traits::FromPrimitive::from_u128(*value); + + match expected { + Some(expected_value) => { + let decimal = Decimal::from_str(expected_value).unwrap(); + assert_eq!(from_u128, Some(decimal)); + } + None => assert!(from_u128.is_none()), } } }