web-dev-qa-db-ja.com

モジュラス(剰余ではない)関数/操作はありますか?

Rust(ほとんどのプログラミング言語のように)、%演算子は、剰余操作ではなく、剰余操作を実行します。これらの 操作は負の数に対して異なる結果になります

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

ただし、Iwantモジュラスが必要です。

回避策を見つけました((a % b) + b) % b、しかし、そのための機能が既にあるなら、私は車輪を再発明したくありません!

40
Kapichu

Rustにはモジュラス(剰余ではありません!)関数/操作がありますか?

私が知る限り、モジュラー算術関数はありません。

これは、Cでも発生します。Cでは、前述の回避策を使用するのが一般的です:(a % b) + b

C、C++、D、C#、F#、およびJavaでは、%は実際には残りです。 Perlでは、PythonまたはRuby、%はモジュラスです。

言語開発者は常に「正しい数学的な方法」を採用しているわけではないため、厳密な数学者の観点からはコンピューター言語は奇妙に見えるかもしれません。問題は、モジュラスと剰余の両方が異なる用途に適していることです。

モジュラスは必要に応じてより数学的であり、剰余(Cファミリー内)は次の条件を満たす一般的な整数除算と一致します:(a / b) * b + a % b = a;これは古いFortranから採用されています。そう %は剰余と呼ばれ、RustはCと一致していると思います。

これに注意するのはあなたが最初ではありません:

20
JosEduSol

いいえ、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 }
6
ideasman42

RFC 2196 ユークリッド除算に関連する整数メソッドをいくつか追加します。具体的には、rem_euclidメソッド( i32 )はあなたが探しているものです:

println!("{}", -1i32 % 4);                // -1
println!("{}", (-21i32).rem_euclid(4));   // 3

このメソッドはrustc 1.38.0(2019-09-27にリリース)以降。

0