2012-08-05 2 views
1

BigInteger 클래스에는 바이트 배열을 반환하는 메서드가 있습니다. 이는 클래스가 숫자를 저장하기 위해 내부적으로 바이트 배열을 사용한다는 사실을 나타 냅니까?BigInteger는 값을 내부적으로 어떻게 저장합니까?

올바른 데이터 형식을 선택하여 이진 데이터를 조작하려면이 점을 알아야합니다. 클래스가 예를 들어 Int64 배열을 사용하는 경우 유사한 배열을 사용하면 모든 호출 함수에서 원시 데이터를보다 효율적으로 조작 할 수 있습니다.

예를 들어 ToByteArray 메서드를 호출하여 특정 이진 패턴을 찾는 바이트를 트래버스합니다.

+5

가 ILSpy이나 반사판 등 디스어셈블러 함께 열어 직접 볼 수행하도록 실행되는 코드이다. – Oded

답변

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 소스 코드 링크. –

관련 문제