【问题标题】:unsigned 16 bit integers in ClojureClojure 中的无符号 16 位整数
【发布时间】:2023-03-19 13:41:01
【问题描述】:

我想在操作数是无符号 16 位整数的 Clojure 中使用 按位 函数(bit-shift-rightbit-and 等)。

16 位整数是从 0 到 65535 的十进制数,或者是从 0000 0000 0000 0000 到 1111 1111 1111 1111 的二进制数。

例如这里的 123 是 java.lang.Long,所以会产生错误的答案:

(bit-not 123)

如何使 123 成为一个无符号的 16 位整数,以便上面生成正确的答案,即十进制的 65412?

所以 0000 0000 0111 1011 (123) 应该变成 1111 1111 1000 0100 (65412)。

【问题讨论】:

    标签: java clojure jvm


    【解决方案1】:

    Java(和 Clojure)没有无符号整数类型。 Clojure 大多只提供 32 位有符号整数位操作(unsigned-bit-shift-right 除外,它相当于 Java 中的 >>>)。

    Java 8 确实通过 Integer 和 Long 类的新方法将 16 位整数视为无符号整数提供了有限的支持,这些新方法可以执行一些无符号操作(比较、乘法、除法、余数)。见:http://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html

    在 Java 中存在提供此功能的外部库,例如 https://github.com/jOOQ/jOOU

    【讨论】:

    • char 是一个无符号的 16 位值,尽管任何位操作都会将其扩展为 int
    • 我应该注意什么?它们在哪些方面受到限制?我认为二进制恭维表示的 b/c 几乎所有操作都保持不变。这只是你如何“阅读”价值的问题。对于比较/除法等,您只需要使用等效方法。不过我可能会遗漏一些东西!
    • 我在问 b/c 在我正在编写的应用程序中(在 Clojure 中)进行无符号翻转对我来说非常有用,但我不想用意想不到的东西射自己的脚下线:)
    【解决方案2】:

    这行得通:

    (->> 123
         bit-not
         (bit-and 16rFFFF))
    ;65412
    

    您可以将其缩短为:

    (->> 123
         (bit-and-not 16rFFFF))
    ;65412
    

    我们使用longs 作为未签名ints 的代理。无论您使用哪种语言,JVM 都没有未签名的ints 或longs。

    【讨论】:

    • 我一直在用计算器仔细检查,答案应该是 65412。这也是本参考文献中的 123:adventofcode.com/2015/day/7
    • @ChrisMurphy 哎呀 - 掩码应该是 16rFFFF,而不是 16rFF00。已更正。
    猜你喜欢
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多