Разница между ' mod 'и` rem' в Haskell


В чем именно разница между mod и rem в Haskell?

оба, кажется, дают одинаковые результаты

*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
4 96

4 ответа:

они не совпадают, когда второй аргумент отрицательный:

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

Да, эти функции действуют по-разному. Как определено в официальная документация:

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

в сущности:

если вы знаете, что оба операнда положительны, вы обычно должны использовать quot,rem или quotRem для эффективности.

если вы не знаете, что оба операнда положительны, вам нужно подумать о том, как вы хотите, чтобы результаты выглядели. Вы, наверное, не хочу!--2-->, но не divMod либо. Элемент (x `div` y)*y + (x `mod` y) == x закон очень хороший, но округление деления в сторону отрицательной бесконечности (деление в стиле кнута) часто менее полезно и меньше эффективны, чем сделать 0 <= x `mod` y < y (Евклидово деление).

в случае, если вы хотите только проверить делимость, вы всегда должны использовать rem.

по сути x `mod` y == 0 эквивалентно x `rem` y == 0, а rem быстрее mod.