2013-05-03 2 views
1

Мне нужна помощь в отладке следующей java-программы.Приоритет 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 

Я думаю, что выход должен быть, содержащий только те, и двойки! Если мы думаем об интерпретации x % (2+1), то вывод правильный. Является ли оператор modulo действительно более слабым, чем добавление? Java tutorial говорит, что нет. Или есть что-то еще, что мне не хватает?

+0

Правда это на самом деле не имеет значения для этого примера, но для хорошей практики вы должны, как правило повторно использовать один и тот же случайный объект а не постоянно создавать и отбрасывать. – berry120

+0

Да. Исходный код генерировал только одно случайное число, которое создавало сумасшедшие значения. Я старался не менять многое, поэтому я просто скопировал, что там есть. :-) Благодаря! – Notinlist

ответ

3

Обратите внимание, что

Random.nextInt() 

может привести к негативным Интс и что в Java, результат остаточного оператора ('%') принимает the sign of the left-hand operand. Это отличается от языков программирования - см. this table in the Wikipedia entry for Modulo for a sampling.

Если вы хотите только неотрицательные INTS, использование:

Random.nextInt(Integer.MAX_VALUE) 

производить Интс между 0 (включительно) и 2^31-1 (эксклюзив). В противном случае, если вы хотите, чтобы справиться с возможным отрицательным результатом по модулю и по-прежнему получить обратно только 1-й или 2-х, а затем использовать:

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

===

JavaDoc для Random.nextInt (курсив мой):

public int nextInt() Возвращает следующее псевдослучайное, равномерно распределенное значение int из этой последовательности генераторов случайных чисел. Общий договор nextInt заключается в том, что одно значение int равно псевдослучайно сгенерировано и возвращено. Все 2^32 возможных значений int производятся с (приблизительно) равной вероятностью.

public int nextInt(int n) Возвращает псевдохаотическом равномерно распределенную INT значения в диапазоне от 0 (включительно) и заданного значения (исключительного), составленное из последовательности этого случайного числа генератора.

===

языка Java Spec относительно the sign of the result of '%'

... Из этого правила, что результат операции остатка может быть отрицательным, только если делимое отрицательно, и может быть положительным, только если дивиденд положителен. ...

+1

' new Random(). NextInt (2) + 1 будет окончательным решением. Благодаря! – Notinlist

4

это потому, что отрицательное число% 2 = -1, а затем +1 приводит к 0.

;)

+0

'Math.abs (x)% 2 + 1' it :-) – Notinlist

1

Модульное-ки положительное число в Java с отрицательным одной воли, возвращающей отрицательный результат - что, вероятно, там, где вы получаете поведение, которого вы не ожидаете.

Может быть, вы хотите что-то вроде:

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

Это точно не определено, насколько математика идти, и, таким образом, различные языки будет осуществлять это по-разному - так это то, чтобы следить за вообще. Например, в Паскале результат будет положительным (как вы, вероятно, ожидали для этого примера), и, по крайней мере, на C89, он не определен и, следовательно, тоже может это сделать!

1

Guava'sIntMath класс предлагает всегда положительную операцию по модулю:

System.out.println(IntMath.mod(x, 2) +1); 
Смежные вопросы