我是 Erlang 的新手。你如何做模(得到除法的余数)?在大多数类 C 语言中它是 %,但它在 Erlang 中指定了一个注释。
有几个人用 rem 回答,在大多数情况下都可以。但是我正在重新讨论这个问题,因为现在我需要使用负数,而 rem 会为您提供除法的余数,这与负数的模数不同。
在 Erlang 中,5 rem 3.
给2
和-5 rem 3.
给-2
。如果我理解你的问题,你会想-5 rem 3.
给 1,因为-5 = -2 * 3 + 1.
这是做你想做的吗?
mod(X,Y) when X > 0 -> X rem Y;
mod(X,Y) when X < 0 -> Y + X rem Y;
mod(0,Y) -> 0.
erlang 模运算符是rem
Eshell V5.6.4 (abort with ^G)
1> 97 rem 10.
7
我在长生不老药中使用了以下内容:
defp mod(x,y) when x > 0, do: rem(x, y);
defp mod(x,y) when x < 0, do: rem(x, y) + y;
defp mod(0,_y), do: 0
根据这篇博文,它是rem
.
上面的 Y + X rem Y 似乎是错误的: (Y + X) rem Y 或 Y + (X rem Y) 产生不正确的结果。例如:让 Y=3。如果 X=-4,第一种形式返回 -1,如果 X=-3,第二种形式返回 3,它们都不在 [0;3[ 中。
我改用这个:
% Returns the positive remainder of the division of X by Y, in [0;Y[.
% In Erlang, -5 rem 3 is -2, whereas this function will return 1,
% since -5 =-2 * 3 + 1.
modulo(X,Y) when X > 0 ->
X rem Y;
modulo(X,Y) when X < 0 ->
K = (-X div Y)+1,
PositiveX = X + K*Y,
PositiveX rem Y;
modulo(0,_Y) ->
0.
Erlang 余数不适用于负数,因此您必须为负参数编写自己的函数。
mod(A, B) when A > 0 -> A rem B;
mod(A, B) when A < 0 -> mod(A+B, B);
mod(0, _) -> 0.
% console:
3> my:mod(-13, 5).
2
接受的答案是错误的。
rem
行为与现代 C 中的运算符完全相同%
。它使用截断除法。
对于 X<0 和 Y<0,接受的答案失败。考虑mod(-5,-3)
:
C: -5 % -3 == -2
rem: -5 rem -3 == -2
Y + X rem Y: -3 + -5 rem -3 == -5 !! wrong !!
模运算符的替代实现使用地板除法和欧几里得除法。结果是
flooring division: -5 mod -3 == -2
euclidean division: -5 mod -3 == 1
所以
Y + X rem Y
不会为 X < 0 和 Y < 0 重现任何模运算符。
并且rem
按预期工作 - 它使用截断除法。