2012-09-28 29 views
1

考慮下面的代碼(其中byteIndex是int):爪哇 - 位與整數偏移和字節

int bitNumber = b-(8*byteIndex); 
bitMask = 0x8>>(byte)bitNumber; 

當編譯該生成錯誤

error: possible loss of precision 

(需字節,實測值INT) 。

代碼

int bitNumber = b-(8*byteIndex); 
bitMask = 0x8>>2; 

編譯罰款。

這裏有什麼問題,以及如何解決第一個例子允許通過int值進行位移的問題?

編輯:繼評論,這裏是一個更完整的例子:

48) int byteIndex; 
49) byte bitMask; 
50) int bitNumber; 
    // assign value to byteIndex 
67) bitNumber = b-(8*byteIndex); 
68) bitMask = 0x8>>bitNumber; 

並給出了錯誤:

...MyClass.java:68: error: possible loss of precision 
    bitMask = 0x8>>bitNumber; 
      ^
    required: byte 
    found: int 
1 error 
+4

真正的java錯誤有行號。 –

+2

'bitMask'的類型是什麼?而'b'的類型呢? –

+2

如果它們是'int'類型,那麼在我的編譯器中,這兩個代碼都可以正常工作。 –

回答

8

將您shifting線這樣的: -

byte bitMask = (byte)(0x8>>(byte)bitNumber); 

你的RHS,是一個int,需要強制轉換的字節段..

上面的代碼將正常工作。隨着或不的bitNumbercastingbyte

所以,你也可以有: -

byte bitMask = (byte)(0x8>>bitNumber); 

但是,這裏是一個問題 - byte bitMask = 0x8>>3;工作正常..爲什麼這樣?

下面是一些例子來說明它的工作背後的原因,也與final的行爲: -

byte bitMask; 
int varInt1 = 3; 
final int finalVarInt2 = 3; 
final int finalVarInt3 = 4; 

bitMask = 0x8>>varInt1; // 1. Will not work. 
bitMask = 0x8<<3;   // 2. Will work 

bitMask = 0x8<<4;   // 3. Will not work 
bitMask = 0x8<<finalVarInt2; // 1. Will work 
bitMask = 0x8<<finalVarInt3; // 2. Will not work 

這裏的一些推理,解釋了上述行爲: -

  • 的只有在編譯器確定它能夠容納中的值時,RHS的值纔會隱含地爲 LHS的變量..否則,我們必須做Explicit type casting告訴編譯器,我們知道我們在做什麼,只是爲我們做。

現在讓我們考慮所有的情況下,一個接一個(從上面的代碼(1-3,1-2): -

  1. varInt1最初包含。所以價值RHS評估爲。雖然這個價值可能容納到byte變量在個LHS,但是編譯器也知道,這是可以改變的varInt1值。所以如果有什麼的varInt1值,在某些階段更改爲 ..它不會再工作..這就是爲什麼它是不允許的..
  2. 現在,在這種情況下,我們已經明確地使用了Integer Literal這裏,所以編譯器是確保它會byte適應。所以它允許implicit鑄造..
  3. 再次,在這種情況下,已知RHS將評估爲128不能在byte ... 再次失敗被accomodated ..

最後兩種情況是不同於常規變量...因爲它們被聲明爲final,所以它們不能被重新初始化。所以,編譯器可以根據賦值來做出決定..

  1. 在這種情況下,編譯器看到的是,finalVarInt2包含值。所以,RHS評估爲,其可以被容納在byte變量上LHS。現在,因爲變量是final它不能被改變,並且Compiler知道,所以它肯定t * 他的值將永遠是64 * ..所以編譯器允許這樣做。

  2. 在最後一種情況下,值爲finalVarInt3是4 ..類似的推理..不適合在LHS,爲RHS評估爲不能融入byte

+0

謝謝!這樣可行。 – Froskoy

1

在你的第一個例子中,位編號是一個int(32位),當你把它作爲一個字節(8位)時,你將失去高位24位。因此你正在失去精確度。只需關閉播放(字節)。

+0

我已經省略了演員陣容,但我仍然得到完全相同的錯誤? bitMask是一個字節,我應該在之前說過。 – Froskoy

+0

我在Java 1.6中沒有這樣的錯誤...您使用的是什麼JVM? – Betlista

+0

java -version打印: java版本「1.7.0_06-icedtea」 – Froskoy

0

其實這是沒有答案的,正確的答案是一個羅希特耆那教寫了,但是這是我第一次看到JVM的這種行爲,比較這些代碼:

版本,其中bitNumber標記爲最終

final int bitNumber = 10; 
final byte bitMask = 0x8 >> bitNumber; 

版本,其中bitNumber不是最終

int bitNumber = 10; 
bitNumber = 10; 
final byte bitMask = 0x8 >> bitNumber; 

而且有錯誤是第二個例子,可能是一些優化。如果有人知道原因,這將是很好的;-)

+0

@Betlista ..我編輯我的帖子來解釋行爲..你可以檢查.. –