Rescaling a value with significant scale 28 to scale 29 creates a value with scale 29 and overflows on subtraction
david-monroe opened this issue · 1 comments
david-monroe commented
fn main() {
let mut num = dec!(0.0000000000000000000000000001);
dbg!(num);
num.rescale(29);
dbg!(num);
dbg!(num.scale());
dbg!(num - dec!(0.1));
}
[src/main.rs:6] num = 0.0000000000000000000000000001
[src/main.rs:8] num = 0.00000000000000000000000000010
[src/main.rs:9] num.scale() = 29
[src/main.rs:10] num - dec!(0.1) = -9999999999999999999999999990
Note that num.rescale(30)
creates a value with scale 30 but does not overflow.
This happens when reading values with large scale from a database.
paupino commented
Thanks for raising this. I performed some analysis and found that (long story short) scale 29 was causing an issue since it was "aligning" to a scale of 29 however reconstructing to a scale of 28. Because a scale of 29 is technically unsupported (except for very small numbers) it made sense to instead force scaling to 28 which effectively solves the issue.
To note, it didn't happen for scale of 30 since the very small number leaked into the high word triggering a full rescale. For scale 28 we didn't see the issue either since it was already within scale.