在Erlang中如何求模或余数?

b5lpy0ml  于 2022-12-08  发布在  Erlang
关注(0)|答案(8)|浏览(211)

I'm brand new to Erlang. How do you do modulo (get the remainder of a division)? It's % in most C-like languages, but that designates a comment in Erlang.
Several people answered with rem, which in most cases is fine. But I'm revisiting this because now I need to use negative numbers and rem gives you the remainder of a division, which is not the same as modulo for negative numbers.

9vw9lbht

9vw9lbht1#

在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.
woobm2wo

woobm2wo2#

Erlang模运算符是rem

Eshell V5.6.4  (abort with ^G)
1> 97 rem 10.
7
0vvn1miw

0vvn1miw3#

我用了以下药剂:

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
9bfwbjaz

9bfwbjaz5#

上面的Y + X雷姆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.
n6lpvg4x

n6lpvg4x6#

Erlang余数不适用于负数,因此您必须为负数参数编写自己的函数。

brccelvz

brccelvz7#

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
wz3gfoph

wz3gfoph8#

The accepted answer is wrong.
rem behaves exactly like the % operator in modern C. It uses truncated division.
The accepted answer fails for X<0 and Y<0. Consider mod(-5,-3) :

C:                     -5 % -3 == -2
rem:                 -5 rem -3 == -2
Y + X rem Y:    -3 + -5 rem -3 == -5 !! wrong !!

The alternative implementations for the modulo operator use floored division and Euclidean division. The results for those are

flooring division:   -5 mod -3 == -2
euclidean division:  -5 mod -3 == 1

So

Y + X rem Y

doesn't reproduce any modulo operator for X < 0 and Y < 0.
And rem works as expected -- it's using truncated division.

相关问题