我想实现以下伪代码,其中/**
* Get the format for database stored dates.
*
* @return string
*/
public function getDateFormat()
{
return 'Y-m-d H:i:s.u';
}
/**
* Convert a DateTime to a storable string.
* SQL Server will not accept 6 digit second fragment (PHP default: see getDateFormat Y-m-d H:i:s.u)
* trim three digits off the value returned from the parent.
*
* @param \DateTime|int $value
* @return string
*/
public function fromDateTime($value)
{
return substr(parent::fromDateTime($value), 0, -3);
}
是一个字节,a
是一个字节。
b
我会在Scala中编写它,就像下面的代码片段一样,但我不认为Java会有很大的不同。
因此,如果字节值的范围从0到255(含),我可以写:
(a + b) mod 256
但Java / Scala类型(a + b) % 256
已签名,范围从-128到127(含)。我可以写:
Byte
这对我来说似乎不必要地复杂,但我不知道def f1(a: Byte, b: Byte): Byte = (((a + 128 + b + 128) % 256) - 128).toByte
对负值的行为如何。此外,我不知道是否可以使用xor或类似的东西简化此功能。
如何根据%
类型实现和简化功能?
或更一般:
如何使用带有符号字节的模数?
修改
上面的函数f1不正确。应该是:
Byte
因为我的,与简化版本的比较是错误的。所以这种简化的方法应该有效:
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
的前4个字节中的前3个将被删除,等于模运算。函数Int
和f1
现在返回相同的结果。测试了所有256 * 256种可能的输入变化。
答案 0 :(得分:0)
这是一个简化版本:
def f2(a: Byte, b: Byte): Byte = (a + b).toByte
我编辑了这个问题并在那里解释了答案,因为我犯了一个错误,包含在问题中。
答案 1 :(得分: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