How do you do modulo or remainder in Erlang?

孤者浪人 提交于 2019-12-18 12:12:07

问题


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.


回答1:


In Erlang, 5 rem 3. gives 2, and -5 rem 3. gives -2. If I understand your question, you would want -5 rem 3. to give 1 instead, since -5 = -2 * 3 + 1.

Does this do what you want?

mod(X,Y) when X > 0 -> X rem Y;
mod(X,Y) when X < 0 -> Y + X rem Y;
mod(0,Y) -> 0.



回答2:


The erlang modulo operator is rem

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



回答3:


I used the following in elixir:

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

Please don't downvote this because it's another language than the question. We all live the dream, because we all have the beam.




回答4:


According to this blog post, it's rem.




回答5:


The above Y + X rem Y seems to be wrong: either (Y + X) rem Y or Y + (X rem Y) yield incorrect results. Ex: let Y=3. If X=-4, the first form returns -1, if X=-3 the second form returns 3, none of which is in [0;3[.

I use this instead:

% 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.



回答6:


Erlang remainder not works with negative numbers, so you have to write your own function for negative parameters.




回答7:


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



回答8:


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.



来源:https://stackoverflow.com/questions/353224/how-do-you-do-modulo-or-remainder-in-erlang

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!