2013-09-30 13 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,以避免溢出短褲,

號沒有溢出是可能的,因此不能成爲理由。原因是與其他可能溢出的操作(即+, - ,*,/)保持一致。