Skip to content
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

Scaling string representation differs from dividing by 10^x #627

Open
Zarathustra2 opened this issue Nov 30, 2023 · 4 comments
Open

Scaling string representation differs from dividing by 10^x #627

Zarathustra2 opened this issue Nov 30, 2023 · 4 comments

Comments

@Zarathustra2
Copy link

Zarathustra2 commented Nov 30, 2023

Hi there,

#[test]
fn scaling_issue() {
    let num = 3850;
    let dec = Decimal::from(num) / Decimal::ONE_THOUSAND;
    
    let mut dec_scale = Decimal::from(num);
    dec_scale.set_scale(3).unwrap();
 
    // Passes
    assert_eq!(dec, dec_scale);
    // Fails
    assert_eq!(dec.to_string(), dec_scale.to_string());
    // thread 'scaling_issue' panicked at 'assertion failed: `(left == right)`
    //  left: `"3.85"`,
    // right: `"3.850"`', tests/decimal_tests.rs:4818:5
    // note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

    // dec 3.85 flags 131072 hi 0 lo 385 mid 0
    // dec_scale 3.850 flags 196608 hi 0 lo 3850 mid 0
}

Is this intended behaviour? If so is there a way to make scaling behave the same way as if I would divided by any 10^x number so that when I convert it to String I don't have any trailing zeros?

Best regards,
Dario

@Tony-Samuels
Copy link
Collaborator

Tony-Samuels commented Nov 30, 2023

@Zarathustra2
Copy link
Author

Ah awesome!

Should the docs of set_scale maybe be adjusted so that future users know about it?

@paupino
Copy link
Owner

paupino commented Dec 1, 2023

Thanks @Tony-Samuels for your reply - exactly right.

@Zarathustra2 - I think there is always an opportunity to make the documentation clearer. In this case, would it help to describe what set_scale is doing under the hood? i.e. we maintain the same mantissa, but just change where the decimal point is - hence retaining precision without rounding. e.g. in this example 3850 is having the decimal point moved to the left 3 places.

@Zarathustra2
Copy link
Author

@paupino Yes some clearer docs would be nice. Maybe we can also add a code example directly to the docs as example. I personally think a coding example with comments is more clear than plain text.

    let num = 3850;
    let dec = Decimal::from(num) / Decimal::ONE_THOUSAND;
    
    let mut dec_scale = Decimal::from(num);
    dec_scale.set_scale(3).unwrap();
 
    // Passes since same number
    assert_eq!(dec, dec_scale);
    assert_eq!(dec.to_string(), "3.85".to_string());
    // set_scale just moves the decimal point and keeps original mantisse. 
    // this effects the string representation but both dec & dec_scale represent
    // the same number
    assert_eq!(dec_scale.to_string(), "3.850".to_string());
    assert_eq!(dec_scale, dec);
    assert_ne!(dec_scale.to_string(), dec.to_string());
    // Use normalize to normalize the mantisse
    assert_eq!(dec_scale.normalize().to_string(), "3.85".to_string());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants