FlagsAttribute Enum problems
So I'm building an MSNP (windows live messenger) client. And I've got this list of capabilities
public enum UserCapabilities : long
{
None = 0,
MobileOnline = 1 << 0,
MSN8User = 1 << 1,
RendersGif = 1 << 2,
....
MsgrVersion7 = 1 << 30,
MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,
}
full list here http://paste.pocoo.org/show/383240/
The server sends each users capabilities to the client as a long integer, which I take and cast it to UserCapabilities
capabilities = Int64.Parse(e.Command.Args[3]);
user._capabilities = (UserCapabilities)capabilities;
This is fine, and with atleast one user (with a capability value of 1879474220), I can do
Debug.WriteLine(_msgr.GetUser(usr).Capabilities);
and this will output
RendersGif, RendersIsf, SupportsChunking, IsBot, SupportsSChannel, SupportsSipInvite, MsgrVersion5, MsgrVersion6, MsgrVersion7
But with another user, who has the capability value of (3055849760), when I do the same, I just get the same number outputted
3055849760
What I would like to be seeing is a list of capabilities, as it is with the other user.
I'm sure there is a very valid reason for this hap开发者_StackOverflowpening, but no matter how hard I try to phrase the question to Google, I am not finding an answer.
Please help me :)
The definition of the shift operators means that only the 5 least significant bits are used for 32-bit numbers and only the first 6 bits for 64-bit; meaning:
1 << 5
is identical to
1 << 37
(both are 32
)
By making it:
MsgrVersion9 = 1L << 32
you make it a 64-bit number, which is why @leppie's fix works; otherwise the <<
is considered first (and note that 1<<32
is identical to 1<<0
, i.e. 1
), and then the resulting 1
is converted to a long
; so it is still 1
.
From §14.8 in the ECMA spec:
For the predefined operators, the number of bits to shift is computed as follows:
- When the type of x is
int
oruint
, the shift count is given by the low-order five bits of count. In other words, the shift count is computed fromcount & 0x1F
.- When the type of x is
long
orulong
, the shift count is given by the low-order six bits of count. In other words, the shift count is computed fromcount & 0x3F
.If the resulting shift count is zero, the shift operators simply return the value of x.
Shift operations never cause overflows and produce the same results in checked and unchecked context
The problem could be with arithmetic overflow.
Specifically at:
MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,
I suggest you make it:
MsgrVersion8 = 1L << 31,
MsgrVersion9 = 1L << 32,
To prevent accidental overflow.
Update:
Seems likely as the smaller number on 'touches' 31 bits, while the bigger one 'touches' 32 bits.
精彩评论