2015-08-27 28 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 
相关问题