akubera / bigdecimal-rs

Arbitrary precision decimal crate for Rust
Other
302 stars 73 forks source link

Support for specifying max number of decimals #124

Open rellfy opened 9 months ago

rellfy commented 9 months ago

My use case requires a maximum number of decimals for all numbers.

I am not aware of a setting to enforce that globally at the moment, so the only way to achieve that is to always call .with_scale(x) after every operation which is very verbose and error-prone.

akubera commented 8 months ago

There's a bunch of work-in-progress branches for adding "Context support" to the arithmetic operations, but they're taking a while.

// keep operation results to 25 digits 
let ctx = Context::new().with_precision(25).unwrap();

let c = ctx.add(a, b);
let z = ctx.mul(x, y);

Is that what you're looking for?

Until those are done you'll have to use the with_scale() methods to trim them yourself.

rellfy commented 8 months ago

@akubera thanks for the response.

I actually specifically need to set the scale, not the precision. But that would work yes (assuming I can set the scale on the context), but even better would be a global max_scale setting which would apply to all BigDecimals by default.

I have a fork where I did some work on that, and it works for divisions but it's failing for multiplications so I need to finish the implementation. Happy to open a PR if it's something that you would be open to merging eventually.

akubera commented 8 months ago

Well in that case I wonder what you think about adding the ability to use precision or a fixed (max) scale in the Context.

Right now it's just the total precision

pub struct Context {
    /// total number of digits
    precision: NonZeroU64,
    /// how to round
    rounding: RoundingMode,
}

But we could do something like:

enum DigitLimiter {
  /// total number of digits
  Precision(NonZeroU64),
  /// Max number of digits after the decimal point
  MaxScale(i64),
}

pub struct Context {
    /// total number of digits
    digit_limit: DigitLimiter,
    /// how to round
    rounding: RoundingMode,
}