是否存在模数(非余数)函数/运算?

Kap*_*chu 42 modulo rust

在Rust中(与大多数编程语言一样),%运算符执行余数运算,而不是运算.这些操作对负数有不同的结果:

-21 modulus 4 => 3
-21 remainder 4 => -1
Run Code Online (Sandbox Code Playgroud)
println!("{}", -21 % 4); // -1
Run Code Online (Sandbox Code Playgroud)

但是,我想要模数.

我找到了一个解决方法((a % b) + b) % b,但如果已有功能,我不想重新发明轮子!

Luk*_*odt 47

RFC 2196添加了几个与欧几里德除法相关的整数方法。具体来说,rem_euclid方法(示例链接i32)就是您要搜索的内容:

println!("{}", -1i32 % 4);                // -1
println!("{}", (-21i32).rem_euclid(4));   // 3
Run Code Online (Sandbox Code Playgroud)

此方法适用于rustc 1.38.0(发布于 2019-09-27)及以上版本。

  • 它们也针对未签名的变体实现,尽管无法从该文档中弄清楚它们的作用。为了完整起见,我还会提到“div_euclid()”。但这无论如何应该是选定的答案。 (2认同)

Jos*_*Sol 20

Rust中是否存在模数(非余数!)函数/运算?

据我所知,没有模块化算术功能.

这也发生在C中,通常使用您提到的解决方法:(a % b) + b.

在C,C++,D,C#,F#和Java中,%实际上是其余部分.在Perl,Python或Ruby中,%是模数.

语言开发人员并不总是采用"正确的数学方式",因此从严格的数学家观点看,计算机语言可能看起来很奇怪.问题是模数和余数都适用于不同的用途.

如果你愿意,模数更具数学性,而余数(在C族中)与满足的公共整数除法一致:(a / b) * b + a % b = a; 这是从旧的Fortran采用的.因此%更好地称为余数,我认为Rust与C一致.

你不是第一个注意到这一点的人:

  • 作为一名 C/C++ 程序员,我很尴尬,因为我不知道 `%` 在 C 中也是这样工作的...... (3认同)
  • @JosEduSol在我写这篇文章时,上面的答案显示了`(a%b)+ b`作为计算模量的一种方法,但是我很确定你要写的是这样的:`(((a%b)+ b)%b`。 (3认同)
  • 如果“/”向-无穷大舍入,则满足“(a / b) * b + a mod b = a”。 (3认同)
  • 这不是Rust的空白吗? (2认同)
  • 我将使用%作为余数,但不支持模数吸收... (2认同)

ide*_*n42 6

不,Rust没有内置模数,由于某些原因,请参阅此讨论.

这是一个可能很方便的例子:

///
/// Modulo that handles negative numbers, works the same as Python's `%`.
///
/// eg: `(a + b).modulo(c)`
///
pub trait ModuloSignedExt {
    fn modulo(&self, n: Self) -> Self;
}
macro_rules! modulo_signed_ext_impl {
    ($($t:ty)*) => ($(
        impl ModuloSignedExt for $t {
            #[inline]
            fn modulo(&self, n: Self) -> Self {
                (self % n + n) % n
            }
        }
    )*)
}
modulo_signed_ext_impl! { i8 i16 i32 i64 }
Run Code Online (Sandbox Code Playgroud)