【问题标题】:Why does bitwise AND of two short values result in an int value in Java?为什么两个短值的按位与会导致 Java 中的 int 值?
【发布时间】:2010-02-17 10:06:33
【问题描述】:
short permissions = 0755;
short requested = 0700;
short result = permissions & requested; 

我得到一个编译器错误:

error possible loss of precision
found   : int
required: short

如果我没有完全错,二进制 AND 的结果与最长的操作数一样长。为什么结果是整数?

如果我选择做空,性能会受到影响吗?

(short) permissions & requested

【问题讨论】:

    标签: java bit-manipulation


    【解决方案1】:

    简短的回答(哈哈!)是binary numeric promotion

    • 如果任何操作数属于引用类型,则会执行拆箱转换(第 5.1.8 节)。然后:
    • 如果任一操作数为 double 类型,则另一个将转换为 double。
    • 否则,如果任一操作数为浮点类型,则将另一个转换为浮点类型。
    • 否则,如果任一操作数为 long 类型,则将另一个转换为 long。
    • 否则,两个操作数都将转换为 int 类型。

    【讨论】:

    • 编辑更好的答案以包含您喜欢的第二个最佳答案的元素,对两者都投赞成票,并接受更好的(现在通过您的编辑完成)答案。无论如何,这就是我在这种情况下所做的。
    【解决方案2】:

    如果我没有完全错 二进制 AND 与最长的一样长 操作数。为什么结果是整数?

    因为 Java 语言规范说非长整数运算的结果总是一个 int。它可能是这样写的,以承认 32 位 CPU 无论如何在内部都是这样工作的——它们实际上并没有 一种方法来使用短裤进行算术运算。

    如果我选择做空,性能会受到影响吗?

    由于上面给出的原因:不 - 无论如何都必须发生。

    【讨论】:

    • 在 C 中也是一样,只是不需要强制转换。
    【解决方案3】:

    我只是想补充一点,如果您使用算术赋值运算符,您实际上可以避免强制转换。它没有更快或更慢,只是可能很高兴知道的事情。

    short permissions = 0755;
    short requested = 0700;
    short result = permissions;
    result &= requested;
    

    【讨论】:

    • 呃……除非代码对性能至关重要,而且我有无可辩驳的证据表明这个“混淆”版本更快,否则我不会写这个。
    • @Stephen C:不会更快。它在编译时会产生几乎相同的字节码(演员表也在那里),并且如果 result 是一个局部变量,它的执行速度将与演员表版本一样快。尽管如果您已经将其称为混淆,则您永远不必阅读我的任何代码或从其他人那里阅读Spartan Programming
    【解决方案4】:

    实际上,我怀疑您的性能可能会受到影响。对于 intlong 值的按位运算,只有 Java 字节码。因此,permissionrequested 变量中的 short 值需要(理论上)在执行操作之前进行符号扩展。

    (此外,我想你会发现原生的逐位指令仅在 32 位和 64 位中可用。或者如果有 8 位或 16 位版本,它们将采用与 32 位相同的时钟数版本。CPU 数据路径将至少 32 位宽,并且对于和/或/xor 没有办法让更窄的类型更快地工作。)

    此外,即使这三个变量的类型为short,JVM 也会分配相同数量的字节来存储它们。这是 JVM 设计方式的结果。

    因此,如果您使用short 的目的是为了节省空间或时间,那可能无济于事。但唯一可以确定的方法是使用分析器来比较您的应用程序的 shortint 版本......或者更好的是,忘记它。

    【讨论】:

      【解决方案5】:

      & 运算符的操作数将提升为 int,因此结果为 int,如果要将其存储在 result 中,则必须将其转换为 short。我不认为这应该是性能损失,除非编译器不擅长生成代码。

      来自http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.22.1

      当运算符 &、^ 或 | 的两个操作数是可转换(第 5.1.8 节)为原始整数类型的类型,二进制数字提升首先在操作数上执行(第 5.6.2 节)。

      来自http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983

      [...] 否则,两个操作数都转换为 int 类型。

      【讨论】:

        猜你喜欢
        • 2020-11-08
        • 1970-01-01
        • 2019-05-06
        • 2013-08-03
        • 1970-01-01
        • 2011-01-27
        • 1970-01-01
        • 1970-01-01
        • 2018-02-25
        相关资源
        最近更新 更多