标志属性枚举问题
本文关键字:问题 枚举 属性 标志 | 更新日期: 2023-09-27 17:55:22
所以我正在构建一个MSNP(Windows live messenger)客户端。我有这个功能列表
public enum UserCapabilities : long
{
None = 0,
MobileOnline = 1 << 0,
MSN8User = 1 << 1,
RendersGif = 1 << 2,
....
MsgrVersion7 = 1 << 30,
MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,
}
完整列表在这里 http://paste.pocoo.org/show/383240/
服务器将每个用户的能力作为长整数发送到客户端,我将其转换为UserCapabilities
capabilities = Int64.Parse(e.Command.Args[3]);
user._capabilities = (UserCapabilities)capabilities;
这很好,并且至少有一个用户(功能值为 1879474220),我可以做
Debug.WriteLine(_msgr.GetUser(usr).Capabilities);
这将输出
RendersGif, RendersIsf, SupportsChunking, IsBot, SupportsSChannel, SupportsSipInvite, MsgrVersion5, MsgrVersion6, MsgrVersion7
但是对于另一个具有 (3055849760) 能力值的用户,当我做同样的事情时,我只会输出相同的数字
3055849760
我希望看到的是功能列表,就像其他用户一样。
我确信发生这种情况有一个非常正当的理由,但无论我多么努力地向谷歌表达这个问题,我都没有找到答案。
请帮我:)
移位运算符的定义意味着只有 5 个最低有效位用于 32 位数字,只有前 6 位用于 64 位; 含义:
1 << 5
与 相同
1 << 37
(两者都是32
)
通过制作它:
MsgrVersion9 = 1L << 32
你把它变成一个64位的数字,这就是为什么@leppie的修复工作;否则<<
被认为是第一个(请注意,1<<32
与1<<0
相同,即 1
),然后将生成的1
转换为long
;所以它仍然1
.
从 ECMA 规范中的 §14.8:
对于预定义的运算符,要移位的位数计算如下:
- 当x的类型是
int
或uint
时,移位计数由低阶五位计数给出。换句话说,班次计数是从count & 0x1F
计算的。- 当x的类型是
long
或ulong
时,移位计数由低阶六位计数给出。换句话说,班次计数是从count & 0x3F
计算的。如果生成的移位计数为零,则移位运算符仅返回 x 的值。
移位操作从不会导致溢出,并在检查和未检查的上下文中产生相同的结果
问题可能出在算术溢出上。
具体在:
MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,
我建议你做到:
MsgrVersion8 = 1L << 31,
MsgrVersion9 = 1L << 32,
防止意外溢出。
更新:
似乎可能是"触摸"31位上的较小数字,而较大的数字"触摸"32位。