31

だから私は MSNP (Windows ライブ メッセンジャー) クライアントを構築しています。そして、私はこの機能のリストを持っています

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;

これで問題ありません。少なくとも 1 人のユーザー (ケイパビリティ値が 1879474220) があれば、次のことができます。

Debug.WriteLine(_msgr.GetUser(usr).Capabilities);

これは出力されます

RendersGif, RendersIsf, SupportsChunking, IsBot, SupportsSChannel, SupportsSipInvite, MsgrVersion5, MsgrVersion6, MsgrVersion7

しかし、(3055849760)の能力値を持つ別のユーザーと同じことをすると、同じ数値が出力されます

3055849760

私が見たいのは、他のユーザーと同じように、機能のリストです。

これには非常に正当な理由があると確信していますが、Google にこの質問をどのように表現しようとしても、答えが見つかりません。

私を助けてください :)

4

2 に答える 2

32

シフト演算子の定義は、32 ビットの数値には最下位 5 ビットのみが使用され、64 ビットの数値には最初の 6 ビットのみが使用されることを意味します。意味:

1 << 5

同じです

1 << 37

(どちらも32)

それを作ることによって:

MsgrVersion9 = 1L << 32

@leppieの修正が機能するのは64ビットの数値にするためです。それ以外の場合は、が最初<<に考慮され (が と同じ、つまりであることに注意してください)、次に結果が に変換されます。まだまだです。1<<32 1<<011long1

ECMA 仕様の §14.8 から:

事前定義された演算子の場合、シフトするビット数は次のように計算されます。

  • xの型がintまたはの場合、シフト カウントはcountuintの下位 5 ビットで与えられます。つまり、シフト カウントは から計算されます。count & 0x1F
  • xの型がlongまたはの場合、シフト カウントはcountulongの下位 6 ビットで与えられます。つまり、シフト カウントは から計算されます。count & 0x3F

結果のシフト カウントがゼロの場合、シフト演算子は単純に x の値を返します。

シフト演算はオーバーフローを引き起こすことはなく、チェックされたコンテキストとチェックされていないコンテキストで同じ結果を生成します

于 2011-05-05T08:10:47.313 に答える
10

問題は、算術オーバーフローにある可能性があります。

具体的には:

MsgrVersion8 = 1 << 31,
MsgrVersion9 = 1 << 32,

私はあなたがそれを作ることをお勧めします:

MsgrVersion8 = 1L << 31,
MsgrVersion9 = 1L << 32,

偶発的なオーバーフローを防ぐため。

アップデート:

「タッチ」31ビットの小さい数値と思われますが、大きい数値は「タッチ」32ビットです。

于 2011-05-05T07:17:45.920 に答える