Різниця між `mod` і` rem` в Haskell


130

Яка саме різниця між Хаскеллом modта remв ньому?

Обидва, здається, дають однакові результати

*Main> mod 2 3
2
*Main> rem 2 3
2
*Main> mod 10 5
0
*Main> rem 10 5
0
*Main> mod 1 0
*** Exception: divide by zero
*Main> rem 1 0
*** Exception: divide by zero
*Main> mod 1 (-1)
0
*Main> rem 1 (-1)
0

3
Не знаю Haskell, але, ймовірно, це та сама операція. ulus mod== remainder.
Меттью Шарлі

Якщо чесно, то це було не те саме питання. Інше питання передбачало розуміння відповіді на це питання.
Ден Бертон

@Dan Читаючи це запитання, через інше питання, яке у мене виникло ( stackoverflow.com/questions/5892188/… ), я зрозумів те саме: /
Оскар Медерос

2
це та ж різниця , як між divіquot
newacct

Відповіді:


181

Вони не однакові, коли другий аргумент є негативним:

2 `mod` (-3)  ==  -1
2 `rem` (-3)  ==  2

20
У мене було те саме питання про remі modв Clojure, і це була відповідь.
noahlz

11
Вони також не відрізняються, коли перший аргумент є негативним. Дивіться stackoverflow.com/a/8111203/1535283 та stackoverflow.com/a/339823/1535283 для отримання додаткової інформації про ці складні операції.
Скотт Олсон

4
Також із stackoverflow.com/a/6964760/205521 здається, що remце найшвидше.
Thomas Ahle

16
Хоча ця відповідь правильна, відповідь, яка стверджує не більше, ніж «не та сама», на питання «яка різниця» є дуже поганою. Я б радий, якби ви могли розширити питання про те, як вони відрізняються, і певні випадки використання.
poitroae

59

Так, ці функції діють по-різному. Як визначено в офіційній документації :

quot це ціле ділення, усічене до нуля

rem є цілим залишком, що задовольняє:

(x `quot` y)*y + (x `rem` y) == x

div це ціле ділення, усічене до негативної нескінченності

mod є цілим модулем, що задовольняє:

(x `div` y)*y + (x `mod` y) == x

Дійсно ви можете помітити різницю, використовуючи від'ємне число як другий параметр, а результат не дорівнює нулю:

5 `mod` 3 == 2
5 `rem` 3 == 2

5 `mod` (-3) == -1
5 `rem` (-3) == 2

(-5) `mod` 3 == 1
(-5) `rem` 3 == -2

(-5) `mod` (-3) == -2
(-5) `rem` (-3) == -2

 


Ваші останні чотири приклади, мабуть, не те, що ви маєте на увазі, оскільки modі remасоціюються сильніше, ніж (-). Я відредагував ваш коментар, оскільки не можу помістити багато рядкових матеріалів у цей коментар.
Ерік Гесселінк

1
@ErikHesselink: ви ввели помилку зі своїм редагуванням. (-5) `mod` 3 == 1
Ченг Сонце

@ChengSun Спасибі, я це виправив. Після огляду має бути в прямому ефірі.
Ерік Гесселінк

16

Практично кажучи:

Якщо ви знаєте , обидва операнда позитивні, зазвичай ви повинні використовувати quot, remабо quotRemдля підвищення ефективності.

Якщо ви не знаєте, що обидва операнди є позитивними, ви повинні подумати над тим, як ви хочете, щоб виглядали результати. Ви, мабуть, не хочете quotRem, але ви можете й не хотіти divMod. (x `div` y)*y + (x `mod` y) == xЗакон є дуже хорошим, але округляючи розподіл в сторону негативної нескінченності (Кнут стиль розподіл) часто менш корисним і менш ефективним , ніж забезпечення того , щоб 0 <= x `mod` y < y(евклидово розподіл).


5

У випадку, якщо ви хочете лише перевірити на подільність, завжди слід використовувати rem.

По суті x `mod` y == 0еквівалент x `rem` y == 0, але remшвидше, ніж mod.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.