Разница между ' 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 ответа:
Да, эти функции действуют по-разному. Как определено в официальная документация:
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
(Евклидово деление).