2010-03-15 8 views
3

Я хочу преобразовать int в массив байтов [2], используя BCD.Преобразование int в массив байтов BCD

Этот вопрос будет исходить из DateTime, представляющего Год, и должен быть преобразован в два байта.

Есть ли готовая функция, которая делает это или вы можете дать мне простой способ сделать это?

пример:

int year = 2010 

выведет:

byte[2]{0x20, 0x10}; 

ответ

9
static byte[] Year2Bcd(int year) { 
     if (year < 0 || year > 9999) throw new ArgumentException(); 
     int bcd = 0; 
     for (int digit = 0; digit < 4; ++digit) { 
      int nibble = year % 10; 
      bcd |= nibble << (digit * 4); 
      year /= 10; 
     } 
     return new byte[] { (byte)((bcd >> 8) & 0xff), (byte)(bcd & 0xff) }; 
    } 

Помните, что вы просили большой обратный порядок байт результата, это немного необычно.

+3

Big-endian может не очень необычно, если он работает со встроенным оборудованием. –

+0

Огромное спасибо! В этом случае я не думаю, что Endian имеет значение, я осторожен с ним, но в этом случае все в порядке. – Roast

3

Вот страшная версия перебором. Я уверен, что есть лучший способ, чем это, но он все равно должен работать.

int digitOne = year/1000; 
int digitTwo = (year - digitOne * 1000)/100; 
int digitThree = (year - digitOne * 1000 - digitTwo * 100)/10; 
int digitFour = year - digitOne * 1000 - digitTwo * 100 - digitThree * 10; 

byte[] bcdYear = new byte[] { digitOne << 4 | digitTwo, digitThree << 4 | digitFour }; 

Печальная часть о том, что быстрый дискретный в BCD преобразования встроены в микропроцессорной архитектуры x86, если вы могли бы получить на них!

2

Вот немного чище версия, то Jeffrey's

static byte[] IntToBCD(int input) 
{ 
    if (input > 9999 || input < 0) 
     throw new ArgumentOutOfRangeException("input"); 

    int thousands = input/1000; 
    int hundreds = (input -= thousands * 1000)/100; 
    int tens = (input -= hundreds * 100)/10; 
    int ones = (input -= tens * 10); 

    byte[] bcd = new byte[] { 
     (byte)(thousands << 4 | hundreds), 
     (byte)(tens << 4 | ones) 
    }; 

    return bcd; 
} 
+1

Возможно, вы можете придумать какой-то сумасшедший способ, который использует логическую логику и смещение ... но это будет намного лучше поддерживать. –

-1
static byte[] IntToBCD(int input) { 
    byte[] bcd = new byte[] { 
     (byte)(input>> 8), 
     (byte)(input& 0x00FF) 
    }; 
    return bcd; 
} 
+2

Это не [BCD] (http://en.wikipedia.org/wiki/Binary-coded_decimal). вы просто конвертируете int в двухбайтовый массив, –

1

Более общее решение

private IEnumerable<Byte> GetBytes(Decimal value) 
    { 
     Byte currentByte = 0; 
     Boolean odd = true; 
     while (value > 0) 
     { 
      if (odd) 
       currentByte = 0; 

      Decimal rest = value % 10; 
      value = (value-rest)/10; 

      currentByte |= (Byte)(odd ? (Byte)rest : (Byte)((Byte)rest << 4)); 

      if(!odd) 
       yield return currentByte; 

      odd = !odd; 
     } 
     if(!odd) 
      yield return currentByte; 
    } 
+0

Вы не должны использовать десятичный символ в качестве входного параметра, если все, что вы можете вычислить, является целым числом. Если вам нужно десятичное число для внутренних вычислений, оно должно оставаться внутренним или как вы вычисляете «GetBytes (3.55549322);»? – Oliver

0

Я сделал общую рутина вывешена на IntToByteArray что вы можете использовать как:

вар yearInBytes = ConvertBigIntToBcd (2010, 2);