2

我正在创建一个掩码并设置更高的位,如下所示:

  enum FLAGS {FLAG1, FLAG2, FLAG3, FLAG4, FLAG5, FLAG6};

  public static void setFlag(short len, FLAGS flag) {
       short mask = 1 << (Short.SIZE - flag.ordinal() - 1);
       len |= mask;
  }

我打印了值:

  len: 0000001111111100
  mask : 1000000000000000
  after OR'ing with mask: 11111111111111111000001111111100

我知道当我们对短裤进行位操作时,它们会被升级为 int 以避免溢出,但是为什么要设置所有更高的位呢?我怎样才能简单地设置前 6 位中的任何一个而没有任何有趣的转换?

4

4 回答 4

4

short已签名,并且您的掩码为负数。当它扩大到 时,它会被保留int。您可以通过屏蔽掩码使高位为零:

len |= (mask & 0xffff);

现在,那将是 iflen是一个intor long,但由于它很短,所以无论如何它不会那些更高的位。所以实际上,代码的其他部分正在扩大。

于 2013-09-30T18:31:59.837 回答
0

只需将结果转换回短。您在int结果中得到符号扩展,因为0x8000在掩码中设置了位,即符号位。

当我们对短裤进行位操作时,它们会被升级为 int 以避免溢出,

不,不可能有溢出,所以这不是原因。原因是为了与其他可能溢出的操作保持一致,即+、-、*、/。

于 2013-10-01T02:01:57.430 回答
0

看起来你是在 OR'ing 而不是 AND'ing。'|' 是或,'&' 是和。此外,您正在 OR'ing 一个 short 和一个 int,而不是一个 short 和一个 short。你的打印语句甚至说 OR'ing,而你的标题说 AND'ing。如果你使用 '&=' 我相信它会解决你的问题。

于 2013-09-30T18:33:17.477 回答
0

short转换为时int,它的数值被保留。如果最高位为 1,则short是负数,并且要保留其值,则int必须为负 - 也就是说,最高位int也必须为 1,介于两者之间的所有位也必须为 1。

通常,将 a 转换为 a 时shortint负数左填充 1,正数左填充 0。

于 2013-09-30T18:49:40.097 回答