我有一個字節變量:爲什麼Java無符號位移位的負字節是如此奇怪?
byte varB = (byte) -1; // binary view: 1111 1111
我想看到兩個最左邊位,做一個無符號右移 6位數:
varB = (byte) (varB >>> 6);
但我得到-1好像它是int型,並得到只有我換了30!
我該如何解決這個問題,並只用6位數的班次得到結果?
我有一個字節變量:爲什麼Java無符號位移位的負字節是如此奇怪?
byte varB = (byte) -1; // binary view: 1111 1111
我想看到兩個最左邊位,做一個無符號右移 6位數:
varB = (byte) (varB >>> 6);
但我得到-1好像它是int型,並得到只有我換了30!
我該如何解決這個問題,並只用6位數的班次得到結果?
原因是與位移時發生的數字提升int
相關聯的符號擴展。在轉換之前,值varB
被提升爲int
。無符號位右移確實發生,但其影響被丟棄鑄造回byte
,只保留最後8位時:
varB (byte) : 11111111
promoted to int : 11111111 11111111 11111111 11111111
shift right 6 : 00000011 11111111 11111111 11111111
cast to byte : 11111111
您可以使用按位與運營商&
掩蓋了移位前不需要的位。與0xFF
位比較只保留8個最低有效位。
varB = (byte) ((varB & 0xFF) >>> 6);
這裏現在發生了什麼:
varB (byte) : 11111111
promoted to int : 11111111 11111111 11111111 11111111
bit-and mask : 00000000 00000000 00000000 11111111
shift right 6 : 00000000 00000000 00000000 00000011
cast to byte : 00000011
因爲這就是如何在Java字節偏移在語言定義的:https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19。
的要點是小於int的類型會默默擴展爲int,轉移並縮小回來。
使您的單行有效等價的:
byte b = -1; // 1111_1111
int temp = b; // 1111_1111_1111_1111_1111_1111_1111_1111
temp >>>= 6; // 0000_0011_1111_1111_1111_1111_1111_1111
b = (byte) temp; // 1111_1111
要改變只是你需要擴大轉換明確自己與無符號的語義字節(和收縮轉換需要手動是,太) :
byte b = -1; // 1111_1111
int temp = b & 0xFF; // 0000_0000_0000_0000_0000_0000_1111_1111
temp >>>= 6; // 0000_0000_0000_0000_0000_0000_0000_0011
b = (byte) temp; // 0000_0011
對'char','byte'或'short'的所有算術運算首先提升爲int。 – Radiodef