You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中确定泛型整数数据类型所需的位数?

获取IBinaryInteger类型的二进制位数(无需unsafe)

针对.NET 7中实现IBinaryInteger<T>的泛型整数类型,要在不使用unsafe编译的sizeof的前提下获取其二进制位数,以下是几种更优雅的实现方案:

方案1:利用BitLength()方法(最推荐)

IBinaryInteger<T>继承自INumberBase<T>接口,该接口的BitLength()方法会返回表示当前值所需的最小二进制位数。对于T.AllBitsSet(所有位均为1的实例),这个值正好等于类型的总位数,再通过CreateChecked<int>安全转换为int类型:

using System.Numerics;

static int CountBits<T>() where T : IBinaryInteger<T>
{
    return T.CreateChecked<int>(T.AllBitsSet.BitLength());
}

方案2:修正PopCount实现

你之前尝试的PopCount思路是可行的,只需用IBinaryInteger提供的类型转换方法替代强制转换,将PopCount返回的T类型值安全转为int:

static int CountBits<T>() where T : IBinaryInteger<T>
{
    return T.CreateChecked<int>(T.PopCount(T.AllBitsSet));
}

由于T.AllBitsSet的所有位都是1,PopCount的结果就是类型的总位数,CreateChecked会在转换溢出时抛出异常,保证类型安全。

方案3:通过Log2计算位数

利用Log2方法获取最高有效位的索引,加1后得到总位数,再转换为int:

static int CountBits<T>() where T : IBinaryInteger<T>
{
    return T.CreateChecked<int>(T.Log2(T.AllBitsSet) + T.One);
}

该方案对无符号和有符号的IBinaryInteger实现类型均适用,即使是有符号类型的AllBitsSet(补码表示的-1),Log2也能正确计算最高位位置。

现有方案的局限性说明

  • 原GetByteCount()*8方案:仅支持位数为8的倍数的类型,自定义非8倍数位数的类型(如UInt7)会返回错误结果。
  • 循环计数方案:虽然功能正常,但性能略逊(例如UInt128需要循环128次),且代码简洁度不足。

内容的提问来源于stack exchange,提问作者BoCoKeith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:00:35