1

次の Java プログラムのデバッグに助けが必要です。

import java.util.Random;

public class NextInt
{
    public static void main(String[] args)
    {
        for(int i=0; i<20; ++i)
        {
            if(i>0)
                System.out.print(", ");
            int x = (new Random()).nextInt();
            System.out.print( x % 2 + 1);
        }
        System.out.println("");
    }
}

出力します(例):

0, 1, 0, 1, 2, 2, 2, 0, 0, 1, 1, 1, 2, 0, 1, 1, 1, 1, 2, 1

出力には 1 と 2 だけが含まれているはずだったと思います。解釈について考えるとx % (2+1)、出力は正しいです。モジュロ演算子は足し算より本当に弱いですか? Javaチュートリアルはノーと言います。それとも、私が見逃しているものがありますか?

4

4 に答える 4

4

これは、負の数 % 2 = -1 と +1 の結果が 0 になるためです。

;)

于 2013-05-03T16:05:34.527 に答える
3

ご了承ください

Random.nextInt()

Java では、剰余演算子 ('%') の結果は左側のオペランドの符号を取ります。これはプログラミング言語によって異なります。サンプリングについては、Modulo のウィキペディアのエントリにあるこの表を参照してください。

非負の整数のみが必要な場合は、次を使用します。

Random.nextInt(Integer.MAX_VALUE)

0 (含む) と 2^31-1 (含まない) の間の int を生成します。そうではなく、モジュロの可能な負の結果を処理し、それでも 1 または 2 だけを返したい場合は、次を使用します。

System.out.print(Math.abs(x % 2) + 1);

===

JavaDoc for Random.nextInt(強調は私のものです):

public int nextInt()この乱数ジェネレーターのシーケンスから、次の疑似乱数の均一に分散された int 値を返します。nextInt の一般契約では、1 つの int 値が疑似乱数で生成されて返されます。すべての 2^32 の可能な int 値は、(ほぼ) 等しい確率で生成されます。

public int nextInt(int n)この乱数ジェネレーターのシーケンスから引き出された、0 (含む) と指定された value (含まない) の間の均一に分散された疑似乱数の int 値を返します。

===

「%」の結果の符号に関する Java 言語仕様

... この規則から、剰余演算の結果は、被除数が負の場合にのみ負になる可能性があり、被除数が正の場合にのみ正になる可能性があることがわかります。...

于 2013-05-03T16:46:15.853 に答える
1

Guava の IntMathクラスは、常に正のモジュロ演算を提供します。

System.out.println(IntMath.mod(x, 2) +1); 
于 2013-05-12T13:17:00.543 に答える