2008-12-09 11 views
36

Ich bin neu zu Erlang. Wie machst du modulo (bekomme den Rest einer Division)? Es ist% in den meisten C-ähnlichen Sprachen, aber das bezeichnet einen Kommentar in Erlang.Wie macht man Modulo oder Rest in Erlang?

Mehrere Leute antworteten mit rem, was in den meisten Fällen in Ordnung ist. Aber ich bespreche dies, weil ich jetzt negative Zahlen verwenden muss und dir den Rest einer Division gibt, die nicht dasselbe ist wie Modulo für negative Zahlen.

+3

Die Modulo-Operation hat nicht eine klare Definition, btw für C und C++% für negative Umsetzung abhängig (ISO C90) später Standards definieren es genau so, wie Erlang ist für Details http://en.wikipedia.org/wiki/Modulo_operation sehen –

Antwort

33

In Erlang, 5 rem 3. gibt 2, und -5 rem 3. ergibt -2. Wenn ich deine Frage verstehe, möchtest du -5 rem 3. stattdessen 1 geben, da -5 = -2 * 3 + 1.

Macht das was du willst?

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

Dies funktioniert. Aber gibt es wirklich nichts mit Erlang, das das tut? – Matt

+0

nicht gemäß dem Erlang-Referenzhandbuch: http://erlang.org/doc/reference_manual/expressions.html (Abschnitt 6.12) – grifaton

+6

Alternativ: mod (X, Y) -> (X + Y rem Y) rem Y. – Koistinen

26

Der erlang Modulo-Operator ist rem

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

Erlang Rest nicht mit negativen Zahlen funktioniert, so dass Sie Ihre eigene Funktion für negative Parameter zu schreiben.

2

Das obige Y + X Y rem falsch zu sein scheint: entweder (Y + X) rem Y oder Y + (X rem Y) falsche Ergebnisse liefern. Bsp .: Lassen Sie Y = 3. Wenn X = -4, gibt die erste Form -1 zurück, wenn X = -3, die zweite Form gibt 3 zurück, von denen keine in [0; 3 [.

Ich benutze diese stattdessen:

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

Die akzeptierte Antwort falsch ist.

rem verhält sich genau wie der Operator % in modernen C. Es verwendet abgeschnittene Division.

Die akzeptierte Antwort nicht für X < 0 und Y Bedenken Sie:

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

Die alternativen Implementierungen für die Modulo-Operator Verwendung platt Division und Division mit Rest. Die Ergebnisse für diejenigen, sind

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

So

Y + X rem Y 

keine Modulo-Operator für X < 0 und Y < 0.

Und rem funktioniert wie erwartet nicht reproduzieren - es ist mit abgestumpften Aufteilung.

5

verwendete ich folgendes in Elixier:

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 

Bitte nicht downvote, weil sie eine andere Sprache als die Frage ist. Wir alle leben den Traum, weil wir alle den Strahl haben.