在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)及以上版本。
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一致.
你不是第一个注意到这一点的人:
不,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)
| 归档时间: |
|
| 查看次数: |
13849 次 |
| 最近记录: |