2010-05-09 83 views
4

當應該沒有AFAIK時,我收到「精度丟失」錯誤。「可能的精度損失」是Java發瘋了還是我錯過了什麼?

這是一個實例變量:

byte move=0; 

這種情況發生在這個類的一個方法:

this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF); 

舉動是一個字節,移動仍是一個字節,其餘的是被鑄造到一個字節。

我得到這個錯誤:

[javac] /Users/looris/Sviluppo/dumdedum/client/src/net/looris/android/toutry/Guy.java:245: possible loss of precision 
[javac] found : int 
[javac] required: byte 
[javac]    this.move=(this.move<<4)|(byte)(Guy.moven.indexOf("left")&0xF); 
[javac]          ^

我已經嘗試了許多變化,但我仍然得到同樣的錯誤。

我現在無能爲力。

+1

如果移動是128,該怎麼辦?當您將它移位4位時,會導致精度損失。 「byte << N」定義爲返回另一個字節,還是一個int? – 2010-05-09 20:50:17

回答

8

實際上,所有邏輯運算符(& | ^)都會返回一個int,而不考慮它們的操作數。您還必須輸出x | y的最終結果。

+0

哦!謝謝! (以leonbloy和ZZ太) – 2010-05-09 21:59:23

8

這是因爲this.move<<4返回一個int。

當Java的發現a shift operator它適用unary promotion到每個操作數;在這種情況下,兩個操作數都被提升爲int,結果也是如此。 其他Java運算符的行爲相似;請參閱相關的指導性討論,「Varying behavior for possible loss of precision」。

+0

該鏈接對我來說非常有用,但沒有關於按位移的示例。有關複合賦值語句的解釋。 – CEGRD 2012-11-29 18:57:05

5

按位或操作數都受到二元數值提升。下面是它的如何在JLS定義,

5.6.2 Binary Numeric Promotion

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value of a numeric type, the following rules apply, in order, using widening conversion (§5.1.2) to convert operands as necessary:

  • If either operand is of type double, the other is converted to double.
  • Otherwise, if either operand is of type float, the other is converted to float.
  • Otherwise, if either operand is of type long, the other is
    converted to long.
  • Otherwise, both operands are converted to type int.

正如你所看到的,沒有字節類型,因此所有字節提升默認爲int。你必須將其轉換回字節以擺脫警告,

this.move=(byte)((this.move<<4)|(Guy.moven.indexOf("left")&0xF)); 
+0

實際上這裏對一元數值提升ocurr,而不是二進制看到的http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#5121 – leonbloy 2012-11-29 19:07:09

相關問題