1

モジュラス関数を作成する必要があります (プリミティブ mod 関数を使用せずに繰り返し減算を使用)。

mod' :: Int -> Int -> Int
mod' x 0 = 0
mod' 0 x = x
mod' x y | x >= y =  (mod' (x-y) y)
         | otherwise = y

私はこれをしましたが、これは機能していません。コンパイルされますが、次のような間違った答えが得られます。

*Main> 7 `mod'` 4
4
*Main> 3 `mod'` 5
5

なにが問題ですか?

4

2 に答える 2

4

作業を行った行とは別にmod' x y | x >= y = (mod' (x-y) y)、2 つの引数を転置する役割がありました。mod' x yは「x mod'y , the remainder on dividingx byy」を意味します。

mod' :: Int -> Int -> Int
mod' x 0 = x
mod' 0 x = 0
mod' x y | x >= y =  (mod' (x-y) y)
         | otherwise = x

ゼロ

divそしてmod方程式から来ます

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

y==0であるから、 は方程式を機能させるべきである_ * 00主張することができます。ただし、これは が であるため、非正格を想定しています。Haskell では、は厳密なので、いずれにせよ方程式は崩れます。おそらく、黙って先に進むよりも、ゼロ除算を含む計算を行ったことをユーザーに警告する方がよいでしょう。x `mod` 0x*x `div` yerror "divide by zero"*

mod' _ 0 = error "division by zero"

とにかく、modは負の数に対してどのように機能するはずですか?

OK、重要なことは、これは剰余であるため、 と 0x `mod` yの間にあるはずでyあり、 に等しくないためy、次のように計算できるということ7 `mod` 3です。

答えが 3 未満になるまで繰り返し 3 を取る

さて、何かを見るとどうなるmod (-3)でしょうか?ここで、「~の間y」とは、剰余が負になることを意味するため、次のように計算できます(-7) `mod` (-3)

答えが -3 を超えるまでマイナス 3 を繰り返します

もちろん、マイナス 3 を取ることは 3 を足すことと同じですが、重要な点は、符号を変えるだけで、同じ計算と答えが得られるということです。

(-x) `mod` (-y) = -(x `mod` y)

xどちらの場合も、との符号がy一致しました。それらが異なる場合はどうなりますか?まず、正の値を持つことができますy:

答えが 0 より大きくなるまで 3 を繰り返し足す

第二に、負の値を持つことができますy:

答えがゼロ以下になるまでマイナス3を繰り返し足す

ご覧のとおり、方法は異なりますが、符号規則の変更

(-x) `mod` (-y) = -(x `mod` y)

まだ立っています。

では、関数に何をすべきでしょうか?

ステップ 0: ゼロのチェック ステップ 1: 負のチェックy. その場合は、符号規則の変更を使用します。
ステップ 2: 陽性を確認しxます。もしそうならy、あなたが下になるまで服用してくださいy
ステップ 3: それ以外の場合は、ゼロを超えるまで追加yします。

コードでは、それは

mod' :: Int -> Int -> Int
mod' x 0 = error "mod by zero"
mod' 0 x = 0
mod' x y | y < 0 = - (mod' (-x) (-y))
         | x > 0 = modpos x
         | otherwise = modneg x
where
  modpos x | x < y = x
           | otherwise = modpos (x-y)
  modneg x | x >= 0 = x
           | otherwise = modneg (x+y) 

そして簡単なチェック:

ghci> all id [x `mod` y == x `mod'` y | x <- [-10 .. 10], y<- [-10 .. 10],y/=0]
True

ロジックが正しいことを示しています。

于 2013-05-19T19:59:16.870 に答える
4

otherwise = y

これは間違っています: when x < y, x mod y == x.

また、x `mod` 0エラーになるべきではありませんか?

編集:そして、mod' 0 x = 0xではありません。

于 2013-05-19T16:23:13.877 に答える