2013-05-03 105 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)解釋,那麼輸出是正確的。模運算符是否比加法更弱? Java tutorial說不。還是有什麼我失蹤?

+0

誠然這並不重要,在這個例子中,但好的做法通常應該重新使用相同的隨機對象而不是不斷創建一個並將其扔掉。 – berry120 2013-05-03 16:10:54

+0

是的。原始代碼只生成一個產生瘋狂值的隨機數。我試圖不改變很多東西,所以我只是複製了那裏的東西。 :-) 謝謝! – Notinlist 2013-05-03 16:12:52

回答

3

注意

Random.nextInt() 

可能會產生負整數,並且,在Java,其餘運算符( '%')的結果取得the sign of the left-hand operand。這在編程語言中有所不同 - 請參閱this table in the Wikipedia entry for Modulo for a sampling

如果你想只非負整數,用途:

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)返回一個僞隨機的,均勻分佈 介於0(含)int值和指定值 (不含),從該隨機數生成器的序列繪製。

===

Java語言對於the sign of the result of '%'

規格......從這個規則,其餘操作的結果可以爲負只有當股息爲負如下,只有當分紅是積極的時候才能是積極的。 ...

+1

'new Random()。nextInt(2)+ 1'將是最終的解決方案。謝謝! – Notinlist 2013-05-03 18:12:35

4

這是因爲負號%2 = -1,然後1分的結果爲0

+0

'Math.abs(x)%2 + 1'它是:-) – Notinlist 2013-05-03 16:09:33

1

模-ING在Java中的正數具有負一個會返回一個否定的結果 - 這可能是你得到你不希望的行爲的地方。

也許你想要的東西,如:

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

這不恰恰就定義爲數學去,因而不同的語言會以不同的方式實現這一點 - 因此它的東西,需要提防一般。例如,在Pascal中,結果是肯定的(正如你對這個例子可能預期的那樣),而在C89中,至少它是未定義的,因此可以做到!

1

Guava'sIntMath類提供了一個總爲正模操作:

System.out.println(IntMath.mod(x, 2) +1);