Haskellの `mod`と` rem`の違い


130

違いを正確に何であるmodremHaskellのでは?

どちらも同じ結果になるようです

*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は知りませんが、これらは同じ操作である可能性があります。modulus == remainder。
Matthew Scharley、2011年

公平に言うと、それは同じ質問ではありませんでした。他の質問は、この質問に対する回答の理解を前提としています。
Dan Burton、

@Danその質問を読んで、私が持っていた別の質問(stackoverflow.com/questions/5892188/…)のために、私は同じことを実現しました:/
オスカーメデロス

2
それはdivquot
-newacct 2013

回答:


181

2番目の引数が負の場合、これらは同じではありません。

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

20
Clojure についても同じ質問がremありmodました。これが答えでした。
noahlz

11
最初の引数が負の場合も同じではありません。これらのトリッキーな操作の詳細については、stackoverflow.com / a / 8111203/1535283およびstackoverflow.com/a/339823/1535283をご覧ください。
Scott Olson 2013

4
また、stackoverflow.com / a / 6964760/205521からremは、最速のようです。
トーマスアーレ2014

16
この答えは正しいですが、「違いは何ですか」という質問に対して「同じではない」にすぎないという答えは非常に悪いものです。それらが「どのように」異なっているか、そしておそらくいくつかのユースケースについて拡張できれば、私はそれを歓迎します。
poitroae 2015年

59

はい、これらの機能は異なる動作をします。公式ドキュメントで定義されているように

quot ゼロに向かって切り捨てられた整数除算です

rem 整数の剰余であり、次の条件を満たす。

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

div 負の無限大に向かって切り捨てられた整数除算です

mod 整数モジュラスであり、次の条件を満たす。

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

2番目のパラメーターとして負の数を使用し、結果がゼロではない場合、違いに本当に気付くことができます。

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

 


あなたの最後の4つの例は、以来、あなたは何を意味するか、おそらくではありませんmodし、rem仲間よりも強く(-)。このコメントに複数行のものを入れることができないため、コメントを編集しました。
Erik Hesselink 2015

1
@ErikHesselink:編集でエラーが発生しました。(-5) `mod` 3 == 1
Cheng Sun

@ChengSunありがとう、私はそれを修正しました。レビュー後に公開する必要があります。
Erik Hesselink

16

実際的に言えば:

あなたは両方のオペランドが正である知っている場合は、通常使用する必要がありますquotremまたは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 == 0remより高速ですmod

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.