2010-03-15 3 views
3

Je souhaite convertir un int en un tableau d'octets [2] en utilisant BCD.Conversion d'un int en un tableau d'octets BCD

L'int en question proviendra de DateTime représentant l'année et doit être converti en deux octets.

Y at-il une fonction pré-faite qui fait cela ou pouvez-vous me donner un moyen simple de le faire?

exemple:

int year = 2010 

génèrerait:

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

Répondre

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

Prenez garde que vous avez demandé un résultat grand-boutiste, qui est un peu inhabituel.

+3

Big-endian peut ne pas très inhabituel s'il travaille avec du matériel embarqué. –

+0

Fonctionne très bien merci! Dans ce cas je ne pense pas qu'Endian compte, je fais attention à ça mais dans ce cas ça va. – Roast

3

Voici une terrible version force brute. Je suis sûr qu'il y a un meilleur moyen que celui-ci, mais il devrait fonctionner de toute façon.

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

Le plus triste est que binaire rapide à BCD conversions sont intégrées dans l'architecture microprocesseur x86, si vous pouvez obtenir à eux!

2

Voici une version un peu plus propre, puis 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

Vous pouvez probablement trouver quelque chose de fou qui utilise la logique booléenne et le décalage ... mais ce sera beaucoup plus agréable à maintenir. –

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

Ce n'est pas [BCD] (http://en.wikipedia.org/wiki/Binary-coded_decimal). vous ne faites que convertir l'int en un tableau de deux octets, –

1

solution plus commune

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

Vous ne devriez pas utiliser une décimale comme paramètre d'entrée si tout ce que vous pouvez calculer est un entier. Si vous avez besoin d'un nombre décimal pour votre calcul interne, il doit rester interne ou comment calculer 'GetBytes (3.55549322);'? – Oliver

0

J'ai fait une routine générique affiché à IntToByteArray que vous pouvez utiliser comme:

var = yearInBytes ConvertBigIntToBcd (2010, 2);