2013-09-30 12 views
2

我创建一个面具,像这样在很短的设置较高位:对Java AND'ing的短有短的,它升级为int和返回值怪异

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 

我明白,当我们做位操作短裤他们upgrded为int,以避免溢出,但为什么设置所有的高位呢?我怎么能简单地设置前6位中的任何一个,而没有任何搞笑演员?

+1

除了这个问题,你应该考虑使用'BitSet'来代替。 –

回答

3

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

len |= (mask & 0xffff); 

现在,这将是如果len是一个intlong,但因为它是短期也不会那些高位反正。所以,你的代码的其他部分的扩展正在发生。

+0

无法正常工作..仍然如此。 – user1071840

+0

@ user1071840如果len是负数,它可以类似地在其他地方扩展为负int **,而不是在您显示的代码中。 (无论如何,上面的遮罩是不必要的 - 一个短的不会有这些位,而'len'不能显示你给我们的值)。然而,这是你可以使用的技术(但你也应该考虑BitSet,就像Rohit Jain所建议的那样)。 – kiheru

+0

哦,现在我明白了。这是一种情况:我必须将6个标志值存储在已经设计和填充并且正在使用的标题中。所以我没有这些标志的额外空间。我确实有一个不会占用10位以上的短暂值,所以我们决定使用这6位。在短期内设置最高位是不可避免的,这当然会使其成为负数。我应该怎么走? – user1071840

0

它看起来像你'不'AND'ing。 '|'是或,'&'是。你也是一个短期和整数,而不是短和短。你的印刷声明甚至说OR'ing,而你的标题说'安'。如果您使用'& ='我相信它会解决您的问题。

0

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

通常,在将short转换为int时,负数用左边填充1,正数用左边填充0。

+0

感谢您的解释..请阅读我在上一篇帖子中发布的描述(回复@kiheru)。 – user1071840

0

只是将结果简化。您在int结果中获得了符号扩展名,因为在符号位掩码中设置了0x8000位。

当我们做位操作上他们upgrded为int,以避免溢出短裤,

号没有溢出是可能的,因此不能成为理由。原因是与其他可能溢出的操作(即+, - ,*,/)保持一致。