web-dev-qa-db-fra.com

Comment faites-vous du modulo ou du reste à Erlang?

Je suis tout nouveau à Erlang. Comment faites-vous modulo (obtenir le reste d'une division)? C'est% dans la plupart des langages de type C, mais cela désigne un commentaire en Erlang.

Plusieurs personnes ont répondu avec rem, ce qui est très bien dans la plupart des cas. Mais je revisite cela parce que maintenant je dois utiliser des nombres négatifs et rem vous donne le reste d'une division, ce qui n'est pas la même chose que modulo pour les nombres négatifs.

44
Matt

À Erlang, 5 rem 3. donne 2, et -5 rem 3. donne -2. Si je comprends votre question, vous voudriez -5 rem 3. pour donner 1 à la place, puisque -5 = -2 * 3 + 1.

Est-ce que cela fait ce que vous voulez?

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

L'opérateur erlang modulo est rem

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

J'ai utilisé ce qui suit dans l'élixir:

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

S'il vous plaît, ne réduisez pas cette note car c'est une autre langue que la question. Nous vivons tous le rêve, car nous avons tous le faisceau.

9
Joe Eifert

Selon ce billet de blog , c'est rem.

3
Jon Skeet

Le Y + X rem Y ci-dessus semble être faux: soit (Y + X) rem Y ou Y + (X rem Y) donnent des résultats incorrects. Ex: soit Y = 3. Si X = -4, la première forme renvoie -1, si X = -3 la seconde forme renvoie 3, dont aucune n'est dans [0; 3 [.

Je l'utilise à la place:

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

La réponse acceptée est fausse.

rem se comporte exactement comme l'opérateur % dans le C. moderne. Il utilise une division tronquée.

La réponse acceptée échoue pour X <0 et Y <0. Considérez mod(-5,-3):

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

Les implémentations alternatives pour l'opérateur modulo utilisent la division au sol et la division euclidienne. Les résultats pour ceux-ci sont

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

Alors

Y + X rem Y

ne reproduit aucun opérateur modulo pour X <0 et Y <0.

Et rem fonctionne comme prévu - il utilise une division tronquée.

1
adam
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
zie1ony

Le reste d'Erlang ne fonctionne pas avec des nombres négatifs, vous devez donc écrire votre propre fonction pour les paramètres négatifs.

1
JLarky