【问题标题】:Copy bits from ulong to long in C#在 C# 中将位从 ulong 复制到 long
【发布时间】: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


【解决方案1】:

一个简单的演员像

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

完全保留值中的位。

【讨论】:

  • 不,我想将比特从 ulong 复制到 long,而不是将 long 转换为 ulong。
  • 这将对位进行二进制转换。不知道为什么这被否决了。复制位与转换相同。您可能需要添加unchecked(...)
  • @usr 我对原始编辑投了反对票(在产生当前版本的忍者之前),因为演员走错了方向。 +1 unchecked
  • 好的,我们开始吧...我以为我已经尝试过演员表并得到了错误,但我想我错了!
  • 是的,它在启用溢出检查的情况下编译时抛出了 OverflowException。按照建议将其放入 unchecked 块中可以解决此问题。
猜你喜欢
  • 2017-04-15
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
相关资源
最近更新 更多