Pergunta

Eu quero converter um int em uma matriz de byte [2] usando o BCD.

O INT em questão virá do DateTime representando o ano e deve ser convertido em dois bytes.

Existe alguma função pré-fabricada que faça isso ou você pode me dar uma maneira simples de fazer isso?

exemplo:

int year = 2010

Sairia:

byte[2]{0x20, 0x10};
Foi útil?

Solução

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

Cuidado que você pediu um resultado grande e muito endiano, isso é um pouco incomum.

Outras dicas

Aqui está uma terrível versão da força bruta. Tenho certeza de que há uma maneira melhor do que isso, mas deve funcionar de qualquer maneira.

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

A parte triste é que as conversões binárias rápidas para o BCD são incorporadas na arquitetura do microprocessador x86, se você puder chegar a elas!

Aqui está uma versão um pouco mais limpa então 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;
}

Solução mais comum

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

Eu fiz uma rotina genérica postada em Inttobytearray que você poderia usar como:

var yearenInbytes = convertbigintTobcd (2010, 2);

static byte[] IntToBCD(int input) { 
    byte[] bcd = new byte[] { 
        (byte)(input>> 8), 
        (byte)(input& 0x00FF) 
    };
    return bcd;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top