当我们(按计划)进入Corporate塔中的现代世界时,我正在将一些C代码转换为Scala,或者无论如何我都被告知。
一些C代码使用无符号变量,这些变量具有对其执行的大量位级别(移位)操作。
考虑到我相信Scala(和Java)以及JVM确实都发现了无符号类型外来物,因此我对如何将它们转换为Scala完全停滞不前。
任何建议表示赞赏。
在C和JVM上对无符号数学进行签名之间的唯一区别在于右移运算符。对于无符号数学,请使用逻辑移位(因为您不希望扩展符号),而对于有符号数学,请进行算术移位(保留符号)。这是Two's补码算法的优点之一。
基于此,您所要做的就是将Java / Scala>>
运算符更改为该运算>>>
符,您将得到一点点相同的答案。但是,根据所执行的操作,当您尝试对结果进行某些操作时,例如,如果您想将其打印为无符号整数,可能仍然会遇到问题。
假设您想对Scala中的“无符号”长型进行一些数学运算,并在最后打印结果。只需使用一个普通的long,使用>>>
(逻辑移位)运算符代替>>
,然后在最后将其转换为可以表示无符号值的其他内容。您可以使用@rightfold答案中建议的库,也可以执行以下简单操作:
val x = Long.MaxValue // declare my "unsigned" long
// do some math with it ...
val y = x + 10
// Convert it to the equivalent Scala BigInt
def asUnsigned(unsignedLong: Long) =
(BigInt(unsignedLong >>> 1) << 1) + (unsignedLong & 1)
x
// Long = 9223372036854775807
asUnsigned(y)
// res1: scala.math.BigInt = 9223372036854775817
如果您仅使用Int
s,那么您甚至不必BigInt
在最后转换为,因为aLong
可以容纳答案。只需使用@BrianRoach在上面的评论中建议的方法,即可通过掩蔽高阶字节将Int
“无符号”值转换为等效值Long
。但是,同样,除非绝对必要,否则您不应该进行转换。即使在64位处理器上使用64位JVM,Long
(64位)整数乘法和除法运算也比Int
(32位)慢。(有关更多详细信息,请参阅此问题:64位整数的效率是否低于JVM中32位整数的效率?)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句