Jaka jest dokładnie różnica między mod
iw rem
Haskell?
Wydaje się, że oba dają te same wyniki
*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
mod
==rem
ainder.div
aquot
Odpowiedzi:
Nie są takie same, gdy drugi argument jest ujemny:
źródło
rem
imod
w Clojure i to była odpowiedź.rem
jest najszybszy.Tak, te funkcje działają inaczej. Jak określono w oficjalnej dokumentacji :
quot
jest dzieleniem całkowitoliczbowym obciętym do zerarem
jest resztą całkowitą, spełniającą:div
jest dzieleniem całkowitoliczbowym obciętym w kierunku ujemnej nieskończonościmod
jest modułem całkowitym, spełniającym:Naprawdę możesz zauważyć różnicę, gdy użyjesz liczby ujemnej jako drugiego parametru, a wynik nie będzie zerowy:
źródło
mod
irem
kojarzy się silniej niż(-)
. Zmodyfikowałem Twój komentarz, ponieważ nie mogę umieścić w nim treści wielowierszowych.(-5) `mod` 3 == 1
Praktycznie rzecz biorąc:
Jeśli znasz oba operandy są pozytywne, należy zazwyczaj użyć
quot
,rem
lubquotRem
efektywności.Jeśli nie wiesz, że oba operandy są pozytywne, musisz pomyśleć o tym, jak chcesz, aby wyglądały wyniki. Prawdopodobnie nie chcesz
quotRem
, ale możesz też nie chciećdivMod
.(x `div` y)*y + (x `mod` y) == x
Prawo jest bardzo dobry, ale zaokrąglenie podział ku negatywnej nieskończoności (styl podziału Knuth) jest często mniej przydatne i mniej wydajny niż zapewnienie, że0 <= x `mod` y < y
(euklidesowej podział).źródło
Jeśli chcesz przetestować tylko podzielność, zawsze powinieneś używać
rem
.Zasadniczo
x `mod` y == 0
jest odpowiednikiemx `rem` y == 0
, alerem
jest szybszy niżmod
.źródło