2008-12-09 30 views
36

Soy nuevo en Erlang. ¿Cómo se hace módulo (obtener el resto de una división)? Es% en la mayoría de los lenguajes tipo C, pero eso designa un comentario en Erlang.¿Cómo se hace el módulo o el resto en Erlang?

Varias personas respondieron con rem, que en la mayoría de los casos está bien. Pero estoy revisando esto porque ahora necesito usar números negativos y rem te da el resto de una división, que no es lo mismo que módulo para números negativos.

+3

El funcionamiento del módulo no tiene una definición clara, por cierto para C y C++% para negativo depende de la implementación (ISO C90) los estándares posteriores lo definen exactamente como Erlang para obtener más detalles en http://en.wikipedia.org/wiki/Modulo_operation –

Respuesta

33

En Erlang, 5 rem 3. da 2 y -5 rem 3. da -2. Si entiendo tu pregunta, querrías -5 rem 3. dar 1 en su lugar, ya que -5 = -2 * 3 + 1.

¿Hace esto lo que quieres?

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

Esto funcionará. Pero, ¿no hay realmente nada distribuido con Erlang que haga esto? – Matt

+0

No según el manual de referencia de erlang: http://erlang.org/doc/reference_manual/expressions.html (sección 6.12) – grifaton

+6

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

26

El operador de módulo Erlang es rem

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

Erlang resto no trabaja con números negativos, por lo que tiene que escribir su propia función de parámetros negativos.

2

The Y por encima de + rem X Y parece estar mal: o bien (Y + X) rem Y o Y + (X rem Y) producir resultados incorrectos. Ej: deja que Y = 3. Si X = -4, la primera forma devuelve -1, si X = -3 la segunda forma devuelve 3, ninguna de las cuales está en [0; 3 [.

utilizo este lugar:

% 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

La respuesta aceptada es erróneo.

rem se comporta exactamente igual que el operador % en la moderna C. Utiliza la división truncada.

La respuesta aceptada no para X < 0 e Y < 0. Considérese mod(-5,-3):

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

Las implementaciones alternativas para el uso operador módulo plantas ha división y la división euclidiana. Los resultados para los que son

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

Así

Y + X rem Y 

no se reproduce ningún operador de módulo para X e Y 0.

Y rem funciona como se espera - se trata de utilizar truncada división.

5

He utilizado el siguiente en 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 

Por favor, no downvote esto porque es una lengua distinta a la pregunta. Todos vivimos el sueño, porque todos tenemos el rayo.

Cuestiones relacionadas