Skip to content

Commit

Permalink
Defer zeroes deletion to last steps
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Oct 25, 2023
1 parent dc6eb41 commit d612b43
Showing 1 changed file with 12 additions and 17 deletions.
29 changes: 12 additions & 17 deletions utils/fixed_decimal/src/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,13 +1062,12 @@ impl FixedDecimal {
}

// 3. If the rounding position is *in the middle* of the nonzero digits

if magnitude < self.magnitude {
// 3-a. Calculate the number of digits to retain and remove the rest
// 3a. Calculate the number of digits to retain and remove the rest
let digits_to_retain = crate::ops::i16_abs_sub(self.magnitude, magnitude) as usize;
self.digits.truncate(digits_to_retain);

// 3-b. Truncate to the next coarseness.
// 3b. Truncate to the next coarseness.
'coarseness: {
match coarseness {
RoundingCoarseness::MultiplesOf1 => {
Expand All @@ -1085,7 +1084,7 @@ impl FixedDecimal {
break 'coarseness;
};

let num = match coarseness {
*last_digit = match coarseness {
RoundingCoarseness::MultiplesOf2 => {
// Equivalent to (n / 2) * 2, which truncates to the next
// multiple of two
Expand All @@ -1095,12 +1094,6 @@ impl FixedDecimal {
RoundingCoarseness::MultiplesOf5 => 5,
_ => 0, // Unreachable
};

if num == 0 {
self.digits.pop();
} else {
*last_digit = num;
}
}
RoundingCoarseness::MultiplesOf25 => {
// Temporarily extend the digits to have the correct
Expand All @@ -1116,21 +1109,23 @@ impl FixedDecimal {
let Some((second_last_digit, _)) = digits.split_last_mut() else {
// The number has no other digits aside from the last,
// making it strictly less than 25.
self.digits.pop();
*last_digit = 0;
break 'coarseness;
};

let number = *second_last_digit * 10 + *last_digit;

// All zeroes will be removed below. We can defer the deletion
// to that part.
if number < 25 {
self.digits.truncate(self.digits.len() - 2);
*second_last_digit = 0;
*last_digit = 0;
} else if number < 50 {
*second_last_digit = 2;
*last_digit = 5;
} else if number < 75 {
*second_last_digit = 5;
// Last digit can just be removed since it will be zero.
self.digits.pop();
*last_digit = 0;
} else {
*second_last_digit = 7;
*last_digit = 5;
Expand All @@ -1139,7 +1134,7 @@ impl FixedDecimal {
}
}

// 3-c. Handle the case where `digits` has leading zeros after
// 3c. Handle the case where `digits` has leading zeros after
// truncating to the next coarseness.
let position_last_nonzero_digit = self
.digits
Expand All @@ -1149,7 +1144,7 @@ impl FixedDecimal {
.unwrap_or(0);
self.digits.truncate(position_last_nonzero_digit);

// 3-d. If `digits` had only trailing zeroes after truncating,
// 3d. If `digits` had only trailing zeroes after truncating,
// reset to zero.
if self.digits.is_empty() {
self.magnitude = 0;
Expand Down Expand Up @@ -3596,7 +3591,7 @@ fn test_concatenate() {
}

#[test]
fn test_rounding_increments() {
fn test_rounding_coarseness() {
// Test Truncate Right
let mut dec = FixedDecimal::from(4235970).multiplied_pow10(-3);
assert_eq!("4235.970", dec.to_string());
Expand Down

0 comments on commit d612b43

Please sign in to comment.