So it appears that the .NET performance counter type has an annoying problem: it exposes long
for the counter RawValue while the actual perf counter value in windows is unsigned and cannot be negative. For instance if you have a NumberOfItems64 counter The API will be perfectly happy to accept a negative value, then silently convert it to a very large number. In fact for half the value range of the counter the only way to set it there is to find the correct negative value to pass in!
I assume what is happening here is that they are taking the raw bits from the long
and treating it as an unsigned 64-bit number. The negative values from two's complement are just read as a straight up number for the counter.
So I'm trying to figure out how to coerce C# into just dropping the bits from the ulong
straight into the long
, since that's what the API wants. But C# is being too helpful here... you can't cast or use Convert.ToInt64(ulong)
since it throws overflow exceptions because of the value being too large. I stumbled upon this way of doing the conversion:
Convert.ToInt64(myULong.ToString("X"), 16)
When it converts from a string in non-base 10 it assumes the number is in two's complement and does what I need it to. But it's not ideal because it needs to allocate an object and parse a string for every conversion and this API is going to be performance-critical. Is there a better way in C# to do this?
A simple cast like
ulong value1 = 0xFEDCBA9876543210UL; // 18364758544493064720
long value2 = (long)value1; // -81985529216486896
ulong value3 = (ulong)value2; // 18364758544493064720
preserves the bits in the value exactly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With