🍿

rust_decimalを用いたRustの10進数取り扱いメモ

2024/04/23に公開


スクラップにメモしていたのですが、記事とスクラップで分かれて見返しにくいので記事にすることにしました。rust_decimalクレートを調べた結果のメモです。[rust_decimal "1.35.0"]

前提

Cargo.toml
[dependencies]
rust_decimal = "1.35.0"

サンプルコード

use rust_decimal::prelude::*;

fn main() {
    let d1 = Decimal::new(456, 2);                // 4.56
    let d2 = Decimal::from_str("-4.56").unwrap(); // -4.56
    let d3: Decimal = 123.into();
    // let d4: Decimal = (1.23).into(); // can't cast float to decimal
    let d4 = d2 + d3;
    // let err = d1 + 1_i32; // can't calc with other types

    println!("{}", d4.to_string()); // 118.44
    assert_eq!(d1.to_f64().unwrap(), 4.56_f64);
    assert!(d1 > d2);
    assert!(d3.is_integer());
    assert_eq!(toggle_sign(&d1), d2);
    assert_eq!(toggle_sign(&d2), d1);
    assert_eq!(d2.abs(), d1);

    println!("{}", d1.trunc()); // 4
    println!("{}", d2.trunc()); // -4
    println!("{}", d1.fract()); // 0.56
    println!("{}", d2.fract()); // -0.56
    println!("{}", d1.ceil());  // 5
    println!("{}", d2.ceil());  // -4
    println!("{}", d1.floor()); // 4
    println!("{}", d2.floor()); // -5
    //usual rounding
    println!("{}", d1.round_dp_with_strategy(0, RoundingStrategy::MidpointAwayFromZero)); // 5
    println!("{}", d2.round_dp_with_strategy(0, RoundingStrategy::MidpointAwayFromZero)); // -5
}
fn toggle_sign(dec: &Decimal) -> Decimal {
    if dec.is_zero() { return Decimal::default(); }
    let mut ret_dec = dec.clone();
    ret_dec.set_sign_negative(dec.is_sign_positive());
    ret_dec
}

メモ

  • set_sign_positiveもあるが、set_sign_negativeとほぼ同じ
    • 引数のtrue,falseの結果が反転するだけのため片方だけで表現可能

丸め方法と結果まとめ

  • 実行結果表
    • Decimal.round_dp_with_strategy(0, RoundingStrategy)
RoundingStrategy -7.5 -7.4 -6.5 -6.4 6.4 6.5 7.4 7.5 memo
MidpointNearestEven -8 -7 -6 -6 6 6 7 8 銀行丸め
MidpointAwayFromZero -8 -7 -7 -6 6 7 7 8 四捨五入
MidpointTowardZero -7 -7 -6 -6 6 6 7 7
ToZero -7 -7 -6 -6 6 6 7 7 切り捨て
AwayFromZero -8 -8 -7 -7 7 7 8 8 切り上げ
ToNegativeInfinity -8 -8 -7 -7 6 6 7 7
ToPositiveInfinity -7 -7 -6 -6 7 7 8 8

参考文献

Discussion