【发布时间】:2012-10-14 21:46:21
【问题描述】:
因此,.NET performance counter type 似乎有一个烦人的问题:它为计数器 RawValue 公开了long,而 Windows 中的实际性能计数器值是无符号的,不能为负数。例如,如果您有一个 NumberOfItems64 计数器,API 将非常乐意接受一个负值,然后默默地将其转换为一个非常大的数字。事实上,对于计数器值范围的一半,设置它的唯一方法是找到要传入的正确负值!
我假设这里发生的事情是他们从 long 中获取原始位并将其视为无符号 64 位数字。二进制补码中的负值仅作为计数器的直数读取。
所以我试图弄清楚如何强制 C# 将位从 ulong 直接放入 long,因为这正是 API 想要的。但是 C# 在这里太有用了……你不能转换或使用Convert.ToInt64(ulong),因为它会因为值太大而引发溢出异常。我偶然发现了这种转换方式:
Convert.ToInt64(myULong.ToString("X"), 16)
当它从非基数 10 中的字符串转换时,它假定该数字是二进制补码并执行我需要的操作。但这并不理想,因为它需要为每次转换分配一个对象并解析一个字符串,而且这个 API 将是性能关键的。在 C# 中有没有更好的方法来做到这一点?
【问题讨论】:
-
您能否举一个导致演员表溢出异常问题的代码示例?我可以做到
long signed = long.MaxValue; signed++; ulong unsigned = (ulong)signed;没有例外。 -
@Will: 你是用
/checked+编译的吗?行为可能会改变。此外,您可以只说ulong unsigned = (ulong)long.MinValue;和long signed = (long)ulong.MaxValue;,它们都保留位但更改值。 -
@Ben - 好问题 - 我只是在运行 Linqpad,所以我不确定它的设置是什么。
-
好的,让它工作。我只需要在
unchecked块内进行强制转换。
标签: c# .net type-conversion