akubera / bigdecimal-rs

Arbitrary precision decimal crate for Rust
Other
284 stars 71 forks source link

panicked at 'called `Option::unwrap()` #98

Closed yamelsenih closed 1 year ago

yamelsenih commented 1 year ago

Exist a error trying rounding a long number

Test Case

Expected result: 118.64 Result:

panicked at 'called `Option::unwrap()` on a `None` value'  bigdecimal-0.3.0/src/lib.rs:594:43

I see that the problem is trying convert the number to i128 here

Screenshot from 2023-04-18 11-51-14

/// Return number rounded to round_digits precision after the decimal point
    pub fn round(&self, round_digits: i64) -> BigDecimal {
        let (bigint, decimal_part_digits) = self.as_bigint_and_exponent();
        let need_to_round_digits = decimal_part_digits - round_digits;
        if round_digits >= 0 && need_to_round_digits <= 0 {
            return self.clone();
        }

        let mut number = bigint.to_i128().unwrap();
        if number < 0 {
            number = -number;
        }
        for _ in 0..(need_to_round_digits - 1) {
            number /= 10;
        }
        let digit = number % 10;

        if digit <= 4 {
            self.with_scale(round_digits)
        } else if bigint.is_negative() {
            self.with_scale(round_digits) - BigDecimal::new(BigInt::from(1), round_digits)
        } else {
            self.with_scale(round_digits) + BigDecimal::new(BigInt::from(1), round_digits)
        }
    }

My bigdecimal version installed is: bigdecimal = { version = "0.3.0" , features = ["serde"] }

Some Solution

I think that a simple solution can be trunc the number if the digits is to long that i128 support

Best regards.

yamelsenih commented 1 year ago

Duplicated here #90