【问题标题】:Unsigned variables in ScalaScala中的无符号变量
【发布时间】:2014-01-19 22:32:30
【问题描述】:

我正在将一些 C 代码转换为 Scala,因为我们正在(据称)进入公司大楼的现代世界,至少有人告诉我。

一些 C 代码使用无符号变量,这些变量对它们执行了大量的位级(移位)操作。

鉴于我相信 Scala(和 Java)和 JVM 都发现了无符号类型,我对如何将它们转换为 Scala 完全停滞不前。

任何建议表示赞赏。

【问题讨论】:

  • C 中无符号变量的类型是什么? (例如charintlong等)
  • 您好,所有操作都是无符号的,没有定义类型,所以我假设 K&R 风格,因此是整数。
  • 下面的答案是一个很好的答案,尤其是对于 scala,但作为一个仅供参考,您可以通过 long l = i & 0x00000000ffffffffL; 向上转换为有符号长整数(64 位),其中 i 是 Java 无符号整数.或者,如果这些不是来自外部来源......只需使用long

标签: java scala


【解决方案1】:

在 C 和 JVM 中签署无符号数学的唯一区别在于右移运算符。对于无符号数学,您使用 逻辑移位(因为您不需要符号扩展),而对于有符号数学,您使用 算术移位(保留符号)。这是Two's complement arithmetic的美女之一。

基于此,您只需将 Java/Scala 的 >> 运算符更改为 >>> 运算符,您将得到相同的答案,一点一点。但是,根据您正在做的事情,当您尝试对结果做某事时,它可能仍然会出现问题,例如如果您想将其打印为无符号整数。

假设您想在 Scala 中使用“无符号”长整数进行一些数学运算,并在最后打印结果。只需使用普通的 long,使用 >>> (logical shift) 运算符代替 >>,然后在末尾将其转换为可以表示无符号值的其他内容。您可以使用@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

如果您只是使用Ints,那么您甚至不必在最后转换为BigInt,因为Long 可以保存答案。只需使用@BrianRoach 在上面的评论中建议的方法,通过屏蔽高阶字节将Int 的“无符号”值转换为等效的Long。但是,再一次,您不应该进行转换,除非您绝对必须这样做。即使在 64 位处理器上使用 64 位 JVM,Long(64 位)的整数乘法和除法运算也会比Int(32 位)慢。 (有关更多详细信息,请参阅此问题:Are 64 bit integers less efficient than 32 bit integers in the JVM?)。

【讨论】:

    【解决方案2】:

    不幸的是,JVM 不支持无符号数据类型(除了char,感谢 Erwin),但还是有希望的! Scala 有一个足够先进的类型系统,允许您创建自己的类型,就像无符号类型一样!

    甚至有a library 已经做到了!该库重载运算符并提供转换。

    【讨论】:

    • JVM 有一种无符号 16 位数据类型:charchar ch = 65535; System.out.println((int) ch); 打印 65535
    • @ErwinBolwidt 你是对的。但是,如果您在发表此评论前一小时阅读了对问题的 cmets,则 OP 正在谈论 32 位整数。
    • @BrianRoach 我知道 OP 是,但我正在回应 rightfold 的声明,即 JVM 没有无符号数据类型,这并不完全正确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 2015-12-28
    • 2013-08-04
    • 1970-01-01
    • 2015-06-10
    • 2012-06-28
    相关资源
    最近更新 更多