-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement remaining rounding to increment methods #4246
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good but I think it's worth some additional exploration on how to do more code sharing. I left an idea for how that might be able to work.
utils/fixed_decimal/src/decimal.rs
Outdated
// This essentially expands to the "even" increments, | ||
// or the increments that are in the even places on the | ||
// rounding range: [0, 4, 8] | ||
// Equivalent to `(current_digit / 2) is odd`. | ||
(current_digit >> 1) & 0x01 == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically you need to look at two digits because this is periodic every 20 not every 10:
- 1 => down to 0
- 3 => up to 4
- 5 => down to 4
- 7 => up to 8
- 9 => down to 8
- 11 => up to 12
- 13 => down to 12
- 15 => up to 16
- 17 => down to 16
- 19 => up to 20
- 21 => down to 20
- ...
utils/fixed_decimal/src/decimal.rs
Outdated
/// assert_eq!("9.98", dec.to_string()); | ||
/// ``` | ||
pub fn half_trunc_to_increment(&mut self, position: i16, increment: RoundingIncrement) { | ||
fn next_digits_exceed_five(number: &mut FixedDecimal, position: i16) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: it may be helpful to add the following private function on FixedDecimal and use it wherever you need it:
enum HalfAtMagnitude {
LessThanHalf,
ExactlyHalf,
GreaterThanHalf,
}
fn half_at_magnitude(&self, magnitude: i16) -> HalfAtMagnitude {
match (self.nonzero_magnitude_end().cmp(magnitude)), self.digit_at(magnitude).cmp(5)) {
(Ordering::Less, Ordering::Less) => LessThanHalf, // 0.1x
(Ordering::Less, _) => GreaterThanHalf, // 0.5x, 0.9x
(Ordering::Equal, Ordering::Less) => LessThanHalf, // 0.1
(Ordering::Equal, Ordering::Equal) => ExactlyHalf, // 0.5
(Ordering::Equal, Ordering::Greater) => GreaterThanHalf, // 0.9
(Ordering::Greater, _) => debug_assert!(false, "don't call this function in this case"),
}
}
You can use this function as part of checking for boundaries at 0.5, 2.5, 7.5, 12.5, 37.5, 62.5, 87.5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to slightly modify the method since it was more useful to use the digits at the right of magnitude
, and opted for using Ordering
because I think it carries the same semantics as HalfAtMagnitude
.
f721efa
to
96bf784
Compare
🎉 All dependencies have been resolved ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! This looks great! Two requests:
- I think there may be extra diffs that would be resolved by merging main into your branch
- It would be nice to see a different type of test that is more data-driven, more like the ECMAScript rounding table test but for increments.
b9b9c70
to
24fe5b5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Thank you!
I have a suggestion on the new ecma402 table test but you can do it later if you prefer.
@robertbastian How are we doing on the 1.4 release? Should we land this PR? It completes the set of experimental rounding increment functions.
("ceil", FixedDecimal::ceil_to_increment, "-1.4", "0.4", "0.6", "0.6", "1.6"), | ||
("floor", FixedDecimal::floor_to_increment, "-1.6", "0.4", "0.4", "0.6", "1.4"), | ||
("expand", FixedDecimal::expand_to_increment, "-1.6", "0.4", "0.6", "0.6", "1.6"), | ||
("trunc", FixedDecimal::trunc_to_increment, "-1.4", "0.4", "0.4", "0.6", "1.4"), | ||
("half_ceil", FixedDecimal::half_ceil_to_increment, "-1.4", "0.4", "0.6", "0.6", "1.6"), | ||
("half_floor", FixedDecimal::half_floor_to_increment, "-1.6", "0.4", "0.4", "0.6", "1.4"), | ||
("half_expand", FixedDecimal::half_expand_to_increment, "-1.6", "0.4", "0.6", "0.6", "1.6"), | ||
("half_trunc", FixedDecimal::half_trunc_to_increment, "-1.4", "0.4", "0.4", "0.6", "1.4"), | ||
("half_even", FixedDecimal::half_even_to_increment, "-1.6", "0.4", "0.4", "0.6", "1.6"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Make sure the test cases on each row are unique. For example, currently "ceil"
and "half_ceil"
have the same expectations, so the test does not distinguish between those two cases. You might need to change the input numbers to make this work.
Yeah, I reused the current test to ensure this is at least considered for 1.4, just to not deliver an incomplete, even if experimental, feature. I'll modify the test to be more exhaustive before stabilizing the new API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reapproving based on Shane's approval, happy to get this in 1.4 as it's all experimental.
d24a07a
to
72e3394
Compare
Please don't force push once a review has started, it's not possible to tell if anything changed. |
Oh, I rebased because I assumed this cannot be merged without being based off of main. Should I use merge commits in that case? |
I don't think it had any conflicts, in which case it could have been merged (we squash-merge). If there are conflicts please use merge commits. |
Good to know! I have rebased previous PRs a couple of times thinking it hadn't been merged because it wasn't based off of main 😅 |
This one hasn't been merged since my approval because I was waiting for CI to finish. The force push retriggered it 😉 |
Depends on #4270With
trunc_to_increment
andexpand_to_increment
implemented, this finishes implementing the rest of the rounding methods.