我目前正在使用以下方法来获取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);
}
答案 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);
它将不会复制任何内容,并且可以用作您的电话号码的精确估算。