Подтвердить что ты не робот

Существует ли функция/операция модуля (не остатка)?

В Rust (как и большинство языков программирования) оператор % выполняет операцию останова, а не операцию модуля. Эти операции имеют разные результаты для отрицательных чисел:

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

Однако я хочу остаток.

Я нашел обходное решение ((a % b) + b) % b, но я не хочу изобретать колесо, если для этого уже есть функция!

4b9b3361

Ответ 1

Есть ли функция/операция модуля (не остатка!) в Rust?

Насколько я могу судить, нет модулярной арифметической функции.

Это также происходит в C, например, и является общим для использования обходного пути, как вы упомянули: (a % b) + b.

В целом для таких языков, как C, С++, D, С#, F # или Java: % на самом деле является остатком. Хотя в языках сценариев, таких как Perl, Python или Ruby: % - модуль.

Разработчики языка не всегда идут "правильным математическим способом", поэтому компьютерные языки могут быть вначале странными из строгой математики. Дело в том, что как модуль, так и остаток, верны для разных целей. Модуль является более математичным, если вам нравится, в то время как остаток (в C-семействе) согласуется с общим целочисленным делением, удовлетворяющим: (a/b)*b + a%b = a (и это принято из старого Фортрана). Поэтому % лучше назвать остатком, и я полагаю, что Rust согласуется с C.

И, очевидно, вы не первый, отметив это, проверьте эти проблемы на Rust git -hub:

Ответ 2

Нет, у Rust нет встроенного модуля, см. это обсуждение по некоторым причинам.

Вот пример, который может быть полезен для тех, кто наткнулся на эту страницу.

///
/// Modulo that handles negative numbers, works the same as Python `%`.
///
/// 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 }