2015-08-27 29 views
2

我想實現以下僞代碼,其中a是一個字節,b是一個字節。如何使用帶符號字節的模數?

(a + b) mod 256 

我會像下面的代碼片段一樣在Scala中編寫它,但我不認爲它們會對Java有顯着的區別。

因此,如果字節值的範圍從0到255(含)我可以這樣寫:

(a + b) % 256 

但Java/Scala的類型Byte簽署,範圍從-128到127(含)。我可以這樣寫:

def f1(a: Byte, b: Byte): Byte = (((a + 128 + b + 128) % 256) - 128).toByte 

這似乎是不必要的複雜給我,但我不知道%負值的行爲。另外我不知道這個函數是否可以用xor或類似的東西來簡化。

如何根據類型Byte實現並簡化功能?

或更一般:

如何使用模有符號字節?

編輯:

從上面的函數f1是不正確的。它應該是:

def f1(a: Byte, b: Byte): Byte = ((a + b + 128) % 256 - 128).toByte 

因此,我與簡化版本的比較是錯誤的。所以這個簡化的方式應該工作:

def f2(a: Byte, b: Byte): Byte = (a + b).toByte 

兩個值隱式轉換爲Int值和相加。當將其轉換回Byte時,所得到的Int的4個字節中的前3個將被刪除,等於模運算。功能f1f2現在返回相同的結果。測試所有256 * 256可能的輸入變化。

+0

請問你的方法返回你的期待值?例如,如果你的'mod'的結果超過了128,你將會有一個負數。 – fdsa

+0

是的,我預計在某些情況下會返回負值。我想從二進制的角度來看,它們都是一樣的,但在簽名的「字節」類型的情況下,最重要的位被解釋爲值的符號。我認爲0 => +和1 => - 。 – user573215

+0

我懷疑你想要的就是'&0xFF'。 –

回答

0

這是一個簡化版本:

def f2(a: Byte, b: Byte): Byte = (a + b).toByte 

我編輯的問題,並解釋了答案,因爲我做這被列入問題上的錯誤。

0

在Java中,模數運算符%能產生任一0或若干相同的符號被除數的:

-1 % 256 = -1. 

另外,即使Java的簽名byte類型,位模式總是可以被解釋爲一個無符號的值。

100000000 = -128 (signed) = 128 (signed) 

此外,執行算術byte MOD 256是多餘的,因爲鑄造回byte執行這一隱式。

現在讓我們看看在每個溢出的情況下會發生什麼(符號和無符號):

public static void addMod256(byte a, byte b) 
{ 
    byte c = (byte) (a + b); 
    System.out.println("(" + a + " + " + b + ") % 256 = " + c + 
     ". Unsigned: (" + 
     (a & 0xFF) + " + " + (b & 0xFF) + ") % 256 = " + (c & 0xFF) + "."); 
} 

addMod256((byte) 6, (byte) 70);  // No overflow in signed or unsigned bytes 
addMod256((byte) 70, (byte) 70); // Overflow only in signed bytes 
addMod256((byte) -6, (byte) -70); // Overflow only in unsigned bytes 
addMod256((byte) -120, (byte) -120);// Overflow in both signed and unsigned bytes 

輸出:

(6 + 70) % 256 = 76. Unsigned: (6 + 70) % 256 = 76. 
(70 + 70) % 256 = -116. Unsigned: (70 + 70) % 256 = 140. 
(-6 + -70) % 256 = -76. Unsigned: (250 + 186) % 256 = 180. 
(-120 + -120) % 256 = 16. Unsigned: (136 + 136) % 256 = 16. 

的結果是正確的,無論什麼溢出情況是存在的。因此,在Java中,您可以簡單地將它們添加並將結果轉換回byte

public static byte f1(byte a, byte b) 
{ 
    return (byte) (a + b); 
} 

在Scala中,相當於將如你已經表示:

def f2(a: Byte, b: Byte): Byte = (a + b).toByte 
相關問題