2012-10-24 13 views
11

.NET performance counter typeには迷惑な問題があるようです。ウィンドウの実際のパーセンテージカウンタの値は符号なしで負ではないが、カウンタRawValueにはlongが公開されています。たとえば、NumberOfItems64カウンタがある場合、APIは負の値を受け入れ、それを静かに非常に大きな数値に変換することができます。実際にはカウンタの値の半分の範囲では、それを設定する唯一の方法は、渡す正しい負の値を見つけることです!C言語でulongからlongにビットをコピーする

ここで起こっていることは、生のビットをlongから取り出し、符号なし64ビット数として扱っていることです。 2の補数からの負の値は、カウンタのまっすぐな番号として読み取られます。

私はC#をulongのビットをlongにまっすぐに落とす方法を理解しようとしています。それはAPIが望んでいるからです。しかし、C#はあまりにも参考になっています。値が大きすぎるためにオーバーフロー例外がスローされるので、キャストしたり使用したりできません。Convert.ToInt64(ulong)それは数が2の補数であると仮定し、私はそれが必要なものない非ベース10内の文字列から変換するとき

Convert.ToInt64(myULong.ToString("X"), 16)

:私は、変換を行うためのこの方法につまずきました。しかし、理想的ではないのは、オブジェクトを割り当てて変換ごとに文字列を解析する必要があり、このAPIがパフォーマンスに重大な影響を及ぼすためです。これを行うにはC#でより良い方法がありますか?

+0

キャストでオーバーフロー例外の問題を引き起こすコードの例を挙げることはできますか?私は 'long signed = long.MaxValue;を行うことができます。 signed ++; ulong unsigned =(ulong)signed; '例外なし。 –

+1

@Will: '/ checked +'でコンパイルしていますか?動作が変わる可能性があります。また、 'ulong unsigned =(ulong)long.MinValue;'と 'long signed =(long)ulong.MaxValue;'といってもどちらでもビットは保持されますが、値は変更されます。 –

+0

@Ben - 良い質問 - 私はちょうどLinqpadを実行しているので、設定が何であるか分かりません。 –

答えて

18

ulong value1 = 0xFEDCBAUL; // 18364758544493064720 
long value2 = (long)value1;   // -81985529216486896 
ulong value3 = (ulong)value2;   // 18364758544493064720 

のような単純なキャストが正確に値のビットを保持します。

+1

いいえ、私はulongからlongへの変換ではなく、longへのulongからのビットのコピーを行いたいと思います。 – RandomEngy

+6

これは、ビットのバイナリ変換を行います。これがなぜ落とされたのか分かりません。ビットのコピーは変換と同じです。 'unchecked(...)'を追加したいかもしれません。 – usr

+1

@usrキャストが間違った方向に行ったため、私はオリジナルの編集を(現在のバージョンを作成した忍者の前に)下げました。 +1は「未チェック」です。 –

関連する問題