Rust 将有理数64舍入到分数的下一个倍数而不溢出?

Rust 将有理数64舍入到分数的下一个倍数而不溢出?,rust,integer,overflow,rational-number,Rust,Integer,Overflow,Rational Number,我使用num rational板条箱的类型将数字表示为有符号64位整数的比率。我试图将一个数字向下舍入到另一个数字的下一个倍数,当我用两种明显的方法中的任何一种进行舍入时,我会遇到整数溢出问题。请注意,这两个数字都可以是分数 标准化为整数 () 减去余数 () 有没有办法使n四舍五入为增量的倍数以减少整数溢出的可能性?如果我必须提取分子和分母(都是Rusti64类型)并直接对它们进行计算,那就好了。请注意原始代码和当前代码之间的差异。这就是我们要求MCVE的意思。有一个MCVE可以防止你的问题被

我使用num rational板条箱的类型将数字表示为有符号64位整数的比率。我试图将一个数字向下舍入到另一个数字的下一个倍数,当我用两种明显的方法中的任何一种进行舍入时,我会遇到整数溢出问题。请注意,这两个数字都可以是分数

标准化为整数 ()

减去余数 ()


有没有办法使
n
四舍五入为
增量的倍数
以减少整数溢出的可能性?如果我必须提取分子和分母(都是Rust
i64
类型)并直接对它们进行计算,那就好了。

请注意原始代码和当前代码之间的差异。这就是我们要求MCVE的意思。有一个MCVE可以防止你的问题被否决(或关闭),也可以大大增加获得好答案的机会。通过提供一次MCVE,您可以避免强迫每个潜在的回答者重新创建整个设置(猜测类型、猜测值等)。简化的过程有助于你理解核心问题,并使你的问题对将来寻找同样问题的人更有用。基本上,这对每个人来说都是一场胜利。使用64位类型可靠地执行128位算术是一件棘手的事情。你最好把参数转换成
BigRational
s,做算术,然后再转换回来。是的,我最后就是这么做的。我担心性能会受到影响,但对于我的用例来说,这是可以接受的。不过,看看如何做到这一点还是很有趣的。
extern crate num_rational;
extern crate num_traits;

use num_rational::Rational64;
use num_traits::identities::Zero;

fn round(mut n: Rational64, increment: Rational64) -> Rational64 {
    let rem = n % increment;
    if !rem.is_zero() {
        // normalize to a multiple of the increment, round down
        // to the next integer, and then undo the normalization
        n = (n * increment.recip()).trunc() * increment;
    }
    n
}

fn main() {
    let a = Rational64::new(10_000_676_909_441, 8_872_044_800_000_000);
    let b = Rational64::new(1, 1_000_000);
    let c = round(a, b);
    println!("{}", c);
}
extern crate num_rational;
extern crate num_traits;

use num_rational::Rational64;
use num_traits::identities::Zero;

fn round(mut n: Rational64, increment: Rational64) -> Rational64 {
    let rem = n % increment;
    if !rem.is_zero() {
        n -= rem;
    }
    n
}

fn main() {
    let a = Rational64::new(10_000_676_909_441, 8_872_044_800_000_000);
    let b = Rational64::new(1, 1_000_000);
    let c = round(a, b);
    println!("{}", c);
}