2008-12-09 13 views
36

Jestem nowy dla Erlang. Jak zrobić modulo (zdobyć resztę dywizji)? To% w większości języków podobnych do C, ale to oznacza komentarz w Erlang.Jak zrobić modulo lub pozostać w Erlangu?

Kilka osób odpowiedziało rem, co w większości przypadków jest w porządku. Ale powtórzę to, ponieważ teraz potrzebuję użyć liczb ujemnych, a rem daje resztę podziału, która nie jest taka sama jak modulo dla liczb ujemnych.

+3

Operacja modulo nie ma jednoznacznej definicji, btw dla C i C++% dla wartości ujemnej jest zależna od implementacji (ISO C90) późniejsze standardy definiują ją dokładnie jako Erlang dla szczegółów patrz http://pl.wikipedia.org/wiki/Modulo_operation –

Odpowiedz

33

W Erlang, 5 rem 3. daje 2, a -5 rem 3. daje -2. Jeśli rozumiem twoje pytanie, to chciałbyś, aby -5 rem 3. zamiast tego dawało 1, ponieważ -5 = -2 * 3 + 1.

Czy robi to, czego chcesz?

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

To zadziała. Ale czy naprawdę nic nie jest dystrybuowane z erlangiem, który to robi? – Matt

+0

Nie zgodnie z podręcznikiem użytkownika erlang: http://erlang.org/doc/reference_manual/expressions.html (sekcja 6.12) – grifaton

+6

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

26

Operator modulo Erlang jest rem

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

Erlang reszta nie działa z liczb ujemnych, więc trzeba napisać własną funkcję parametrów ujemnych.

2

Powyższy Y + Y X REM wydaje się problem: albo (Y + x) REM Y + lub Y (X REM Y) dostarcza błędne wyniki. Np .: niech Y = 3. Jeśli X = -4, pierwsza forma zwraca -1, jeśli X = -3 druga forma zwraca 3, z których żadna nie jest w [0; 3 [.

Używam tego zamiast:

% 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

Zaakceptowanych odpowiedź jest błędna.

rem zachowuje się dokładnie tak samo, jak operator % w nowoczesnym C. Wykorzystuje obcięty podział.

Zaakceptowanych odpowiedź nie dla X i Y 0 < < 0. Rozważmy mod(-5,-3):

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

alternatywne implementacje dla użycia operatora modulo podłogi i Pion euklidesową. Wyniki dla tych, są

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

Więc

Y + X rem Y 

nie odtwarza żadnego operatora modulo dla X i Y 0 < < 0.

I rem działa zgodnie z oczekiwaniami - to używając ściętego podział.

5

użyłem następujących w eliksiru:

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 

Proszę nie downvote to dlatego, że jest inny język niż pytanie. Wszyscy żyjemy marzeniami, ponieważ wszyscy mamy promień.

Powiązane problemy