-
Notifications
You must be signed in to change notification settings - Fork 186
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
Scale depends on computing order of additions when subsequent result is zero #695
Comments
Balance and Balance-Group need own references for: paupino/rust-decimal#695 Signed-off-by: 35V LG84 <[email protected]>
Balance and Balance-Group need own reference vectors for: paupino/rust-decimal#695 Signed-off-by: 35V LG84 <[email protected]>
Is this behaviour causing an issue? |
Hi, Yes, zeros after a decimal (e.g., 1.0) are significant numbers, and this is causing loss of information. Also it is inconsistent behavior as it depends on computing order: sometimes you have all significant numbers, sometimes not. Concrete issue is that this is breaking a test system, which is validating presence of all significant figures. |
Our You can see that this is almost impossible to guarantee the scale between different calculation ordering with a simple case like Whilst you're considering addition and subtraction instead of multiplication, the underlying principle applies. If you want to check equality, use the existing functions for doing so. |
Hi, this is not about PartialEq failing (the scale is not used for eq comparisions), and this is also not about division, where there are impossible cases like 1 / 3. This is simply about inconsistent behavior with additions and scale. The bug happens when additions and subtraction are done so that chained temporary result is zero. However, if the end result is zero, then it works just fine, which is odd. Mathematically this should preserve max scale, and also rust-decimal is preserving it most of the time. Please see test cases below, which demonstrates this inconsistent behavior: #[test]
fn test_scale() {
// Scale works with high + low
let d1 = dec!(9.000000000) + dec!(3.000);
assert_eq!(d1.scale(), 9);
// Scale works with low + high
let d2 = dec!(3.000) + dec!(9.000000000);
assert_eq!(d2.scale(), 9);
// Scale works when result is zero
let d3 = dec!(3.000) + dec!(-3.000);
assert_eq!(d3.scale(), 3);
// Scale works with mixed scale
let d4 = dec!(3.000) + dec!(2.01) +dec!(-3.000);
assert_eq!(d4.scale(), 3);
// Scale works also with this
// (the computational temp result is not zero)
let d5 = dec!(3.000) + dec!(-4.000) + dec!(2.01);
assert_eq!(d5.scale(), 3);
// Scale doesn't work, when computational temp result is zero
// However, in above case 3.000 + -3.000 scale worked
let d6 = dec!(3.000) + dec!(-3.000) + dec!(2.01);
assert_eq!(d6.scale(), 3); // <--- this assert fails: 2 != 3
} |
Hello,
Decimal's scale depends on computing order of additions, if additions subsequent result is zero:
And one test to check that scale is preserved in normal case:
The text was updated successfully, but these errors were encountered: