Как ты делаешь по модулю или остаток в Erlang? - PullRequest
42 голосов
/ 09 декабря 2008

Я новичок в Эрланге. Как вы делаете по модулю (получить остаток от деления)? Это% в большинстве C-подобных языков, но это обозначает комментарий в Erlang.

Несколько человек ответили rem, что в большинстве случаев нормально. Но я возвращаюсь к этому, потому что теперь мне нужно использовать отрицательные числа, а rem дает вам остаток от деления, который не совпадает с модулем для отрицательных чисел.

Ответы [ 8 ]

37 голосов
/ 13 мая 2009

В Эрланге 5 бэр 3. дает 2, а -5 бэр 3. дает -2. Если я понимаю ваш вопрос, вы бы хотели -5 rem 3. вместо 1 дать -5 = -2 * 3 + 1.

Делает ли это то, что вы хотите?

mod(X,Y) when X > 0 -> X rem Y;
mod(X,Y) when X < 0 -> Y + X rem Y;
mod(0,Y) -> 0.
28 голосов
/ 09 декабря 2008

Оператор эрланга по модулю rem

Eshell V5.6.4  (abort with ^G)
1> 97 rem 10.
7
8 голосов
/ 07 декабря 2016

Я использовал следующее в эликсире:

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

Пожалуйста, не отрицайте это, потому что это другой язык, чем вопрос. Мы все живем мечтой, потому что у всех нас есть луч.

3 голосов
/ 09 декабря 2008

Согласно этому сообщению в блоге , это rem.

2 голосов
/ 05 марта 2010

Представленное выше Y + X rem Y, похоже, неверно: либо (Y + X) rem Y, либо Y + (X rem Y) дают неверные результаты. Пример: пусть Y = 3. Если X = -4, первая форма возвращает -1, если X = -3, вторая форма возвращает 3, ни одна из которых не находится в [0; 3 [.

Я использую это вместо:

% 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 голос
/ 01 июня 2015

Принятый ответ неверен.

rem ведет себя точно так же, как оператор % в современном C. Он использует усеченное деление.

Принятый ответ не подходит для X <0 и Y <0. Рассмотрим <code>mod(-5,-3):

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

Альтернативные реализации для оператора по модулю используют деление по этажам и евклидово деление. Результаты для них

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

So

Y + X rem Y

не воспроизводит никакого оператора по модулю для X <0 и Y <0. </p>

И rem работает как положено - используется усеченное деление.

1 голос
/ 21 мая 2012
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 голос
/ 13 мая 2009

Остаток Эрланга не работает с отрицательными числами, поэтому вы должны написать собственную функцию для отрицательных параметров.

...