2012-08-05 57 views
1

BigInteger類有一個返回字節數組的方法。這是否表示該類在內部也使用字節數組來存儲數字?BigInteger如何在內部存儲值?

爲了選擇正確的數據類型來操縱二進制數據,這一點很重要。例如,如果這個類是使用Int64數組,那麼類似的數組通過任何調用函數來處理原始數據會更有效率。

作爲一個例子,我調用ToByteArray方法來遍歷查找特定二進制模式的字節。

+5

與像ILSpy或反思反彙編器打開它,看看自己的代碼。 – Oded 2012-08-05 19:37:48

回答

5

根據the reference source看來,它存儲的信息爲數據的uint[]和符號的int。

namespace System.Numerics 
{ 
    /// <summary>Represents an arbitrarily large signed integer.</summary> 
    [Serializable] 
    public struct BigInteger : IFormattable, IComparable, IComparable<BigInteger>, IEquatable<BigInteger> 
    { 

    // For values int.MinValue < n <= int.MaxValue, the value is stored in sign 
    // and _bits is null. For all other values, sign is +1 or -1 and the bits are in _bits 
    internal int _sign; 
    internal uint[] _bits; 

這裏是它執行執行ToByteArray()

// Return the value of this BigInteger as a little-endian twos-complement 
    // byte array, using the fewest number of bytes possible. If the value is zero, 
    // return an array of one byte whose element is 0x00. 
    public byte[] ToByteArray() { 
     if (_bits == null && _sign == 0) 
      return new byte[] { 0 }; 

     // We could probably make this more efficient by eliminating one of the passes. 
     // The current code does one pass for uint array -> byte array conversion, 
     // and then another pass to remove unneeded bytes at the top of the array. 
     uint[] dwords; 
     byte highByte; 

     if (_bits == null) { 
      dwords = new uint[] { (uint)_sign }; 
      highByte = (byte)((_sign < 0) ? 0xff : 0x00); 
     } 
     else if(_sign == -1) { 
      dwords = (uint[])_bits.Clone(); 
      NumericsHelpers.DangerousMakeTwosComplement(dwords); // mutates dwords 
      highByte = 0xff; 
     } else { 
      dwords = _bits; 
      highByte = 0x00; 
     } 

     byte[] bytes = new byte[checked(4 * dwords.Length)]; 
     int curByte = 0; 
     uint dword; 
     for (int i = 0; i < dwords.Length; i++) { 
      dword = dwords[i]; 
      for (int j = 0; j < 4; j++) { 
       bytes[curByte++] = (byte)(dword & 0xff); 
       dword >>= 8; 
      } 
     } 

     // find highest significant byte 
     int msb; 
     for (msb = bytes.Length - 1; msb > 0; msb--) { 
      if (bytes[msb] != highByte) break; 
     } 
     // ensure high bit is 0 if positive, 1 if negative 
     bool needExtraByte = (bytes[msb] & 0x80) != (highByte & 0x80); 

     byte[] trimmedBytes = new byte[msb + 1 + (needExtraByte ? 1 : 0)]; 
     Array.Copy(bytes, trimmedBytes, msb + 1); 

     if (needExtraByte) trimmedBytes[trimmedBytes.Length - 1] = highByte; 
     return trimmedBytes; 
    } 
+2

謝謝。鏈接到源代碼+1。 – 2012-08-05 20:12:17