2012-10-24 20 views
11

所以看起来.NET performance counter type有一个令人讨厌的问题:它为计数器RawValue公开long,而窗口中的实际perf计数器值是无符号且不能为负的。例如,如果您有一个NumberOfItems64计数器API将非常乐意接受一个负值,然后将其默默转换为一个非常大的数字。事实上,对于计数器的值范围的一半,设置它的唯一方法是找到传入的正确负值!将位从ulong复制到C#中的位置

我假设这里发生的事情是,他们正在从long采取原始位并将其视为一个无符号的64位数字。来自二进制补码的负值仅作为计数器的直线数字来读取。

所以我想弄清楚如何强迫C#将ulong中的位直接放入long,因为这正是API所要求的。但是C#在这里帮助太大了......你不能投射或使用Convert.ToInt64(ulong),因为它会引发溢出异常,因为值太大。我偶然发现这样做的转换是这样的:

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

当从非基本10字符串转换它假定数量是两个互补和做什么,我需要它。但它并不理想,因为它需要为每次转换分配一个对象并解析一个字符串,并且这个API将会对性能至关重要。 C#中有更好的方法来做到这一点吗?

+0

你能给出一个导致演员溢出异常问题的代码示例吗?我可以做'长签名= 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

这将执行二进制转换的位。不知道为什么这是downvoted。复制位与转换相同。你可能想添加'unchecked(...)'。 – usr

+1

@usr我下了原来的编辑(在制作当前版本的忍者之前),因为演员的方向错了。未选中+1。 –

相关问题