JavaのMODの構文は何ですか


231

擬似コードの例として:

if ((a mod 2) == 0)
{
    isEven = true;
}
else
{
    isEven = false;
}

回答:


357

代わりに、わずかに異なる意味を持つ剰余演算子の、非負整数のために、あなたが使用することができる剰余演算子を%。あなたの正確な例について:

if ((a % 2) == 0)
{
    isEven = true;
}
else
{
    isEven = false;
}

これはワンライナーに簡略化できます:

isEven = (a % 2) == 0;

80
if / elseは不要です。isEven=(a%2)== 0を使用してください
Steve Kuo

59
n(mod m)は常に> = 0ですが、n%mではないため、modおよびmodularという用語に注意してください。n%mは> -mから<mの範囲です。Javaにはintおよびlong型の剰余演算子がありますが、モジュラス関数や演算子はありません。つまり、-12%10 = -2に対して-12 mod 10 = 8です。%演算子がn%mに対して負の値を返す場合、(n%m)+ mはn mod mを返します。BigIntegerは両方に関数を提供し、それらの仕様は違いを非常によく説明しています。また、ゼロにも注意してください。数学では、ゼロは偶数ですが、正でも負でもありません。
ジム

4
@ nl-xおそらく、慣例に任せるよりも優先順位を明示する方が良いためです。私が調べる前に、%それが==以前に評価されたことを知らなかったので、式が(a%2)==0またはに等しいかどうかは不明a%(2==0)です。ブール値が整数と同じではないJavaではあまり重要ではないと思います
Matthew Sainsbury

8
これは係数演算子ではなく、剰余演算子です。投稿を修正してください!
Kieren Johnstone

2
ブール値の偶数=((a&1)== 0)。はるかに簡単です。
mdev 2018年

111

これが最小限のJavaコードでの擬似コードの表現です。

boolean isEven = a % 2 == 0;

それをコンポーネントに分解します。Javaの係数演算子はパーセント文字(%)です。したがって、int%intを取ると、別のintが返されます。二重等号(==)演算子は、整数のペアなどの値を比較してブール値を返すために使用されます。次に、これはブール変数「isEven」に割り当てられます。演算子の優先順位に基づいて、係数は比較の前に評価されます。


12
最低は角かっこなしです;)
プスタントン2010

3
これは剰余演算子であり、係数演算子ではありません。
ローン侯爵

@ user207421その名前は事実である剰余演算子が、彼らは同じではありません:「モジュラス - 4 (計算、プログラミング)。これらの数字の除算の余りを取得するための2つの数字の間に配置されたオペレータ、」?
GeroldBroserが

93

他のすべての人がすでに答えを出したので、もう少しコンテキストを追加します。%「モジュラス」演算子は、実際には剰余演算を実行しています。modとremの違いはわずかですが、重要です。

(-1 mod 2)は通常1を返します。より具体的には、2つの整数XおよびYが与えられると、演算(X mod Y)は[0、Y)の範囲の値を返す傾向があります。言い換えると、XとYの係数は常にゼロ以上、Y未満です。

「%」またはrem演算子を使用して同じ操作を実行すると、X値の符号が維持されます。Xが負の場合、範囲(-Y、0]の結果が得られます。Xが正の場合、範囲[0、Y]の結果が得られます。

多くの場合、この微妙な区別は重要ではありません。コードの質問に戻りますが、「均一性」を解決するには複数の方法があります。

最初のアプローチは特に冗長であるため、初心者には適しています。

// Option 1: Clearest way for beginners
boolean isEven;
if ((a % 2) == 0)
{
  isEven = true
}
else
{
  isEven = false
}

2番目のアプローチは、言語の利点を生かして、より簡潔なコードにつながります。(==演算子がブール値を返すことを忘れないでください。)

// Option 2: Clear, succinct, code
boolean isEven = ((a % 2) == 0);

3番目のアプローチは完全を期するためにここにあり、三項演算子を使用します。三項演算子は非常に便利ですが、この場合は2番目の方法が優れていると考えています。

// Option 3: Ternary operator
boolean isEven = ((a % 2) == 0) ? true : false;

4番目の最後のアプローチは、整数のバイナリ表現の知識を使用することです。最下位ビットが0の場合、数値は偶数です。これは、ビットごとのAND演算子(&)を使用して確認できます。このアプローチは最速ですが(除算の代わりに単純なビットマスキングを行っています)、初心者にはおそらく少し高度で複雑です。

// Option 4: Bitwise-and
boolean isEven = ((a & 1) == 0);

ここでは、ビットごとのAND演算子を使用し、オプション2に示す簡潔な形式で表現しました。オプション1の形式(またはオプション3の形式)でそれを書き換えることは、読者への課題として残されています。;)

お役に立てば幸いです。


ロブありがとう。この混乱により、モジュラー算術からの数学的特性を備えたアルゴリズムを実装する方法をプログラマーに説明することは非常に困難になります。剰余はモジュラスではありませんが、剰余からモジュラスをすばやく導出できます。
ジム

1
@TickledPinkこれがJavaでコンパイルされないことを除いて。
Eugene Beresovsky、

33

負のXおよび正のY値に対してJavaの%(REM)操作をMODのように機能させるには、次のメソッドを使用できます。

private int mod(int x, int y)
{
    int result = x % y;
    if (result < 0)
    {
        result += y;
    }
    return result;
}

または三項演算子を使用します(短いですが、状況によっては不可能または非効率的です):

private int mod(int x, int y)
{
    int result = x % y;
    return result < 0? result + y : result;
}

12

Javaには、Cのようにモジュロ演算子はありません。Javaの%は剰余演算子です。正の整数では、それはモジュロとまったく同じように動作しますが、負の整数では動作が異なり、モジュロとは異なり、浮動小数点数でも動作します。それでも、正の整数以外で%を使用することはめったにないので、それをモジュロと呼びたい場合は、自由に感じてください。


しかし、array[x mod array.length]負の位置にもインデックスを付けるのではなく、常に配列の要素にアクセスできるように、負の整数でも機能する実際のモジュロ演算子が必要です。
クリス

2
(x % y + y) % y またはJava 8以降Math.floorMod(x, y)
グレッグチャールズ

12

値が負かどうかをチェックして適切なモジュロを実行し、負の場合はそれを修正することは可能ですが(多くの人が示唆している方法です)、よりコンパクトなソリューションがあります。

(a % b + b) % b

これは最初にモジュロを行い、値を-b-> + bの範囲に制限し、次にbを追加して値が正であることを確認し、次のモジュロで0-> bの範囲に制限します。

注:bが負の場合、結果も負になります


これは、aとbの両方が大きい場合にオーバーフローする可能性があるため、正しい解決策ではありません。
Trixie Wolf

11

コードはmoduloを使用せずにはるかに高速に実行されます。

public boolean isEven(int a){
    return ( (a & 1) == 0 );
}

public boolean isOdd(int a){
    return ( (a & 1) == 1 );
}

3
これは受け入れられた答えよりもはるかにきれいに見えます。これは時期尚早の最適化とは何の関係もありません。単純に、それが機能するかどうか。
AlexWien 2013

4
@LluisMartinezこれは、コンピューティングで最も誤って引用された格言の1つです。完全な引用は、「プログラマーはプログラムの重要ではない部分の速度について考えたり心配したりすることに膨大な時間を費やしており、これらの効率化の試みは、デバッグとメンテナンスを考慮すると、実際には強い否定的な影響を与えます。効率は、時間の約97%と言います。時期尚早の最適化がすべての悪の根源です。しかし、その重要な3%で機会を逃してはなりません。」これは実際にはかなり異なることを意味します。
ローン侯爵2015年

3
@EJPあなたはおそらく正しいです。私はテスト(100万回のループ)を行いましたが、モジュロで4000ナノ秒、論理ANDで2500ナノ秒かかりました。
Lluis Martinez

なぜこれが答えになるのでしょうか?確かに奇数は実行されますが、mod / remainder演算子では何も実行されません。質問は、奇数の偶数を見つける方法ではなく、mod演算子について話します。
マークウォルシュ



4

Javaではそれがある%:オペレーター 15.17.3。剰余演算子%

存在することに注意してくださいfloorModjava.lang.Mathは異なる結果を与えるクラス%符号の異なる引数のを:

public static int floorMod​(int x, int y)


1
%引数が負の場合にも適切に機能するため、floorModは「modulo」演算子よりも優れているため、賛成です。他の答えはどれも、引数が正でない限り、%は実際には剰余ではないという免責事項が付いているため、実際には正しくありません。特に、すべての整数を配列内の連続した位置にマッピングするarray[floorMod(i, array.length)場合は、インデックスiが負の領域に入っても正しく動作します。とは違い%ます。
クリス

3

また、modは次のように使用できます。

int a = 7;
b = a % 2;

bは1になります7 % 2 = 1


初心者向けの例で、出力なしで複合演算子を使用するのはおそらく間違いです。
Stu Thompson、

3

Javaの剰余演算子は次のとおりです%。モジュロ演算子は次のように表すことができます。

public int mod(int i, int j)
{
  int rem = i % j;
  if (j < 0 && rem > 0)
  {
    return rem + j;
  }
  if (j > 0 && rem < 0)
  {
    return rem + j;
  }
  return rem;
}

2

他の人が指摘したように、%(剰余)演算子は、数学的なmodモジュラス演算/関数と同じではありません 。

mod%

x mod n関数は、マッピングさxnの範囲内[0,n)
一方、x % n演算子はの範囲でマッピングxnれます(-n,n)

数学的なモジュラス演算を使用し、前の符号を気にしない方法を使用するには、以下を使用xできます。

((x % n) + n) % n

多分この写真はそれをよりよく理解するのに役立ちます(私は最初にこれに頭を包むのに苦労しました)

ここに画像の説明を入力してください


1
素敵な絵。もう1つの複雑さ:これは、int変数自体の2 ^ 32のモジュール性を考慮していません。floorModこの方法は、正しくそれを行う(ただし場合は、追加の計算を必要とするかもしれないn否定的です)。
Maarten Bodewes

1

別の方法は:

boolean isEven = false;
if((a % 2) == 0)
{
    isEven = true;
}

しかし、最も簡単な方法はまだです:

boolean isEven = (a % 2) == 0;

@Steve Kuoが言ったように。


0

ではJavamod操作を次のように実行できます。

Math.floorMod(a, b)

注:MOD操作が異なる剰余演算。ではJava残りの操作を次のように実行できます。

a % b

まあ正確ではありません...のjavadocにMath.floorMod()はそれがあります。The floor modulus is x - (floorDiv(x, y) * y), has the same sign as the divisor y, and is in the range of -abs(y) < r < +abs(y).つまり、数学的な係数とはまったく同じではありません。しかし、同じメソッドのJavadocの中でも、ポジティブな結果を取得する方法があります:If the signs of arguments are unknown and a positive modulus is needed it can be computed as (floorMod(x, y) + abs(y)) % abs(y).
WesternGun

@WesternGunそれは本当かもしれませんが、係数が正であることがわかっている場合floorMod操作は期待どおりに機能します。floorModfor long値もありますが、それ以外の場合はBigInteger大きな値があります。
Maarten Bodewes

-1

モジュロ演算子は%(パーセント記号)です。均一性をテストするか、一般に2のべき乗のモジュロ演算を行うには、isEven =!(a&1)のように&(theおよび演算子)を使用することもできます。


-3

@Codyのコードの代替:

モジュラス演算子の使用:

bool isEven = (a % 2) == 0;

これは、if / elseを書くよりもわずかに良いコードだと思います。重複が少なく、未使用の柔軟性があるからです。調査するためにはもう少し頭の力が必要ですが、isEven代償の適切なネーミングです。


2
これは剰余演算子であり、係数演算子ではありません。
ローンの侯爵

@EJP OK 次に、係数演算子とは何ですか?
TheRealChx101 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.