2012-10-24 6 views
11

So scheint es, dass die .NET performance counter type ein lästiges Problem hat: es stellt long für den Zähler RawValue verfügbar, während der tatsächliche Perf-Zähler-Wert in Windows unsigned ist und nicht negativ sein kann. Zum Beispiel, wenn Sie einen NumberOfItems64-Counter haben. Die API wird vollkommen glücklich sein, einen negativen Wert zu akzeptieren, und dann stillschweigend in eine sehr große Zahl konvertieren. Tatsächlich ist es für den halben Wertbereich des Zählers die einzige Möglichkeit, es dort zu setzen, um den korrekten negativen Wert zu finden, der eingeht!Kopieren von Bits von ulong zu lang in C#

Ich nehme an, was passiert hier ist, dass sie die rohen Bits von der long nehmen und es als eine vorzeichenlose 64-Bit-Nummer behandeln. Die negativen Werte aus dem Zweierkomplement werden nur als gerade Zahl für den Zähler gelesen.

Also ich versuche herauszufinden, wie man C# in nur die Bits aus der ulong gerade in die long fallen, da das ist, was die API will. Aber C# ist hier zu hilfreich ... Sie können Convert.ToInt64(ulong) nicht umwandeln oder verwenden, da es Überlauf-Ausnahmen auslöst, weil der Wert zu groß ist. Ich stolperte über diese Art und Weise die Umwandlung zu tun:

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

Wenn es aus einem String in nicht-Basis umwandelt 10 nimmt die Zahl in Zweier-Komplement ist und tut, was ich brauche es. Aber es ist nicht ideal, weil es für jede Konvertierung ein Objekt zuordnen und eine Zeichenfolge parsen muss, und diese API wird leistungskritisch sein. Gibt es einen besseren Weg in C#, dies zu tun?

+0

Können Sie ein Beispiel für einen Code angeben, der das Überlauf-Ausnahmeproblem bei einem Cast verursacht? Ich kann 'long signed = long.MaxValue; signiert ++; ulong unsigned = (ulong) signiert; 'ohne Ausnahmen. –

+1

@Will: Kompilieren Sie mit '/ checked +'? Das Verhalten könnte sich ändern. Man könnte auch einfach sagen: ulong unsigned = (ulong) long.MinValue; 'und' long signed = (long) ulong.MaxValue; ', die beide Bits beibehalten, aber den Wert ändern. –

+0

@Ben - Gute Frage - Ich leite gerade Linqpad, also bin ich nicht sicher, was es Einstellungen sind. –

Antwort

18

Ein einfacher Guss wie

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

bewahrt die Bits im Wert genau.

+1

Nein, ich möchte Bits von einem ulong in einen long kopieren, nicht einen long in einen ulong umwandeln. – RandomEngy

+6

Dies wird eine binäre Umwandlung der Bits vornehmen. Nicht sicher, warum dies abgelehnt wird. Das Kopieren der Bits entspricht dem Konvertieren. Vielleicht möchten Sie 'unchecked (...)' hinzufügen. – usr

+1

@usr Ich habe den Originalschnitt (vor dem Ninja, der die aktuelle Version produziert hat) downvoted, weil der Cast in die falsche Richtung ging. +1 für "unchecked". –