web-dev-qa-db-ja.com

モジュラス演算子をいつ使用するかを認識する

modulus (%)演算子は除算の残りを計算します。モジュラス演算子を使用する必要がある状況を特定するにはどうすればよいですか?

モジュラス演算子を使用して、数値が偶数か奇数か、素数か合成かを確認できることはわかっていますが、それはそれだけです。余りについてはあまり考えません。モジュラス演算子は便利だと思います。これを活用する方法を学びたいと思います。

モジュラス演算子が適用できる場所を特定するのに問題があります。プログラミングのさまざまな状況で、問題を見て「Hey!残りの除算がここで機能する!」ということに気づくのは難しいです。

60
Codebug

秒単位の経過時間があり、これを時間、分、秒に変換したいとします。

h = s / 3600;
m = (s / 60) % 60;
s = s % 60;
25
Paul R
0 % 3 = 0;
1 % 3 = 1;
2 % 3 = 2;
3 % 3 = 0;

あなたはそれが何をしたかを見ましたか?最後のステップでゼロに戻りました。これは、次のような状況で使用できます。

  1. NがM(たとえば、奇数または偶数)で割り切れるかどうか、またはNがMの倍数であるかどうかを確認します。

  2. 特定の値の上限を設けること。この場合3。

  3. 数値の最後のM桁を取得するには-> N%(10 ^ M)。
20
SysAdmin

大きなループの進行を示すプログレスバーなどに使用します。進行状況は、ループをn回おきに、またはcount%n == 0のときにのみ報告されます。

16
SeaDrive

数を特定の倍数に制限するときに使用しました:

temp = x - (x % 10); //Restrict x to being a multiple of 10
11
Bob
  • 値のラップ(時計など)。
  • 対称鍵アルゴリズムに有限フィールドを提供します。
  • ビット演算。

等々。

10
jweyrich

最近見た使用例の1つは、数値を逆にする必要がある場合です。たとえば、123456654321になります。

int number   = 123456;
int reversed = 0;

while ( number > 0 ) {
    # The modulus here retrieves the last digit in the specified number
    # In the first iteration of this loop it's going to be 6, then 5, ...
    # We are multiplying reversed by 10 first, to move the number one decimal place to the left.
    # For example, if we are at the second iteration of this loop, 
    #  reversed gonna be 6, so 6 * 10 + 12345 % 10 => 60 + 5
    reversed = reversed * 10 + number % 10;
    number = number / 10;
}
4
JCM

線形データ構造の行列構造への変換:ここで、aは線形データのインデックスであり、bは行ごとのアイテム数です。

row = a/b
column = a mod b

上記の注は単純化されたロジックです:aは除算する前に-1にオフセットする必要があり、結果は+1に正規化する必要があります。

例:(4行の3行)

1  2  3  4    
5  6  7  8    
9 10 11 12 

(7 - 1)/4 + 1 = 2

7 is in row 2

(7 - 1) mod 4 + 1 = 3 

7 is in column 3

モジュラスのもう1つの一般的な使用法:場所ごとにハッシュする。年と月を6桁の数字195810に格納したいとします。month = 195810 mod 100右から3番目のすべての数字は100で割り切れるので、この場合、残りは右端の2桁であり、月は10です。年を抽出するには195810 / 100は1958を返します。

4
Joe

例。 Xバイトのメッセージがありますが、プロトコルの最大サイズはYおよびY <Xです。メッセージをパケットに分割する小さなアプリを作成してみてください。modに実行されます:)

4
Andrey

除算があり、10進数以外の剰余を表現する場合は常に、mod演算子が適しています。頭に浮かぶのは、通常、残りの部分を人間が読める形式で読みたい場合です。バケットに入れることができるアイテムの数をリストし、「残り5個」と言っておくとよいでしょう。

また、丸め誤差が発生する可能性がある場合は、モジュロ除算が適しています。たとえば、非常に頻繁に3で除算する場合、0.333333を余りとして渡したくないでしょう。余りと除数(つまり、分数)を渡すのが適切です。

3
Matt

なんらかの理由で整数除算を実行して小数を取得する必要があり、整数を小数除算をサポートする数値に変換できない場合、または小数ではなく小数を返す必要がある場合にも、モジュラスは非常に役立ちます。

係数演算子として%を使用します

例えば

2/4 = 0

これを行う場所

2/4 = 0 and 2 % 4 = 2

したがって、あなたは本当におかしくなり、ユーザーが分子と除数を入力できるようにして、結果を整数として表示し、次に小数として表示したいとします。

whole Number = numerator/divisor
fractionNumerator = numerator % divisor
fractionDenominator = divisor

モジュラス除算が役立つもう1つのケースは、数値を増加または減少させて、その数値を特定の範囲の数値に含めたいが、上または下に到達したときに、ただ停止したくない場合です。リストの一番下または一番上にそれぞれループする必要があります。

配列をループしている関数を想像してください。

Function increase Or Decrease(variable As Integer) As Void
    n = (n + variable) % (listString.maxIndex + 1)  
    Print listString[n]
End Function

これがn =(n +変数)%(listString.maxIndex + 1)である理由は、最大インデックスが考慮されるようにするためです。

これらは、デスクトップアプリケーションだけでなく、ロボット工学やシミュレーション環境のプログラミングでも、モジュラスを使用する必要があったもののほんの一部です。

3
msarchet

@jweyrichが言うように、値をラップします。有限のリストがあり、ループで繰り返し処理したいときに、modが非常に便利であることがわかりました。たとえば、グラフシリーズなど、すべてのシリーズを異なるものにしたい、UI要素の色の固定リストのように、可能な範囲ですが、色が足りなくなったら、最初からやり直します。これは、たとえばパターンと一緒に使用することもできるため、2回目に赤が現れると、破線になります。 3回目、点線など-ただし、modは、赤、緑、青、赤、緑、青を永久に取得するために使用されます。

3
Carl Manaster

素数の計算

3
anonymous

モジュロは、合計の分を「時間と分」に変換および分割するのに役立ちます。

時間=分/ 60

minutes_left =分%60

時間ビットでは、小数部分を取り除く必要がありますが、それは使用している言語によって異なります。

その後、それに応じて出力を再配置できます。

3
tony

私のお気に入りの用途は反復です。

増加しているカウンターがあり、既知のリストから対応するアイテムを取得したいが、選択できるアイテムはnだけであり、サイクルを繰り返したいとします。

var indexFromB = (counter-1)%n+1;

結果 (counter=indexFromB)与えられたn=3

`1=1`
`2=2`
`3=3`
`4=1`
`5=2`
`6=3`
...
2
Nateous

それが役立つ多くの例があります。

数値を特定の範囲内に制限する必要がある場合は、modを使用できます。たとえば、0から99までの乱数を生成するには、次のようにします。

num = MyRandFunction() % 100;
2
Justin Ethier
  • 最大公約数の計算
  • 数が回文かどうかの判断
  • 数値が次のみで構成されているかどうかの判断...
  • 数を決定しています...数は...で構成されています...
2
helpermethod

これは、数値が偶数か奇数かを判別する簡単な方法です。 #mod 2を実行するだけです。0の場合は偶数、1の場合は奇数です。

1
user1671033

私が見たモジュラス演算子の最良の使い方は、私たちが持っている配列が元の配列の回転バージョンであるかどうかを確認することです。

A = [1,2,3,4,5,6] B = [5,6,1,2,3,4]

次に、BがAの回転バージョンであるかどうかを確認する方法は?

ステップ1:Aの長さがBの長さと同じでない場合は、回転バージョンではないことを確認してください。

手順2:BのAの最初の要素のインデックスを確認します。ここで、Aの最初の要素は1です。また、Bのそのインデックスは2です(プログラミング言語にゼロから始まるインデックスがあると仮定します)。そのインデックスを変数 "Key"に保存します

ステップ3:次に、BがAのローテーションバージョンであるかどうかを確認する方法は?

これがモジュラス関数が揺さぶる場所です:

for (int i = 0; i< A.length; i++)
{

// here modulus function would check the proper order. Key here is 2 which we recieved from Step 2
   int j = [Key+i]%A.length;

   if (A[i] != B[j])
   {
     return false;
   }
}

return true;