C#System.Numerics.BigInteger幅度估计

时间:2012-10-12 09:00:56

标签: c# biginteger

我目前正在使用以下方法来获取BigInteger的幅度估计值。我很想知道是否有人可以推荐一种不需要使用BigInteger.ToByteArray()的方法;

 public static long MagnitudeEstimate(BigInteger value)
 {

     byte[] array = value.ToByteArray();

     if (array.Length == 0 || (array.Length == 1 && (array[0] == 0 || array[0] == 1)))
         return 0;
     else
         return (long)(array.Length * 2.408239965);
 }

4 个答案:

答案 0 :(得分:1)

转换为double并取对数似乎是一种简单的方法。

Math.Log10((double)bigInt)

或仅仅是内置的

BigInteger.Log10(bigInt)

我没有对它进行基准测试,所以我不知道它有多快。

答案 1 :(得分:1)

hackish 解决方案。我不会用这个。

BigInteger bi = new BigInteger(long.MaxValue);

var fieldInfo = typeof(BigInteger).GetField("_bits", BindingFlags.Instance | BindingFlags.NonPublic);

var arr = (uint[])fieldInfo.GetValue(bi);
var size =  arr.Length * sizeof(uint);

答案 2 :(得分:0)

将我原来的版本和L.B的版本结合起来我已经确定了以下内容。虽然它不比我原来的版本快,但更准确。

非常感谢大家的投入。

public static long MagnitudeEstimate(BigInteger value)
{
      var fieldInfo = typeof(BigInteger).GetField("_bits", BindingFlags.Instance | BindingFlags.NonPublic);
      var arr = (uint[])fieldInfo.GetValue(value);
      if (arr != null)
      {
            int totalNumBytes = arr.Length * sizeof(uint);
            int zeroBytes = 0;
            for (int i = arr.Length - 1; i >= 0; i--)
            {
                  if (arr[i] == 0)
                  {
                        zeroBytes += 4;
                        continue;
                  }
                  else if (arr[i] <= 0xFF)
                        zeroBytes += 3;
                  else if (arr[i] <= 0xFFFF)
                        zeroBytes += 2;
                  else if (arr[i] <= 0xFFFFFF)
                        zeroBytes += 1;

                  break;
            }

            return (long)((totalNumBytes - zeroBytes) * 2.408239965);
      }
      else return 0;
}

答案 3 :(得分:0)

从.NET Core 2.1开始,有一个new API: public int GetByteCount (bool isUnsigned = false);

它将不会复制任何内容,并且可以用作您的电话号码的精确估算。