1

我目前正在使用以下方法来获得 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

4 回答 4

1

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

Math.Log10((double)bigInt)

或者只是内置的

BigInteger.Log10(bigInt)

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

于 2012-10-12T09:13:27.783 回答
1

一个骇人听闻的解决方案。我不会用这个。

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);
于 2012-10-12T09:51:47.170 回答
0

结合我的原始版本和 LB 的版本,我确定了以下内容。虽然它并不比我的原始版本快,但它更准确。

非常感谢大家的意见。

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;
}
于 2012-10-12T11:27:47.030 回答
0

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

它不会复制任何内容,并且可以非常精确地估计您的数量。

于 2019-02-15T19:08:24.163 回答