2012-10-12 49 views
0

我目前使用以下方法來獲取BigInteger的幅度估計值。我很想知道是否有人可以推薦一種不需要使用BigInteger.ToByteArray()的方法;C#System.Numerics.BigInteger幅度估計

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

在發佈代碼,使用'{}'代碼按鈕 - 你會標明你起來作爲一個報價,這使得格式爲奇的第一行和最後一行 –

+2

此外,你不只是問了「某種日誌」? –

+0

@Damien_The_Unbeliever:非常感謝您的糾正。 – MarcF

回答

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; 
} 
1

鑄造加倍和取對數似乎是一個簡單的方法來做到這一點。

Math.Log10((double)bigInt) 

或者乾脆建在

BigInteger.Log10(bigInt) 

我沒有基準,所以我不知道它是多麼快。

+0

非常感謝您的建議,但不幸的是我已經考慮過對數方法(在OP中沒有提及的道歉)。我剛剛做了比較,我現在的方法比BigInteger.Log10快兩倍。不幸的是我之前無法投入翻倍,因爲我的價值是> 10000。 – MarcF

1

A 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);