Pregunta

Quiero convertir un int a un byte [2] matriz mediante BCD.

El int en cuestión vendrá de DateTime que representa el año y debe ser convertido a dos bytes.

¿Hay alguna función de pre-hecho que hace esto o que me puede dar una forma sencilla de hacer esto?

ejemplo:

int year = 2010

seria:

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

Solución

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

Mira que pedirá un resultado big endian, que es un poco inusual.

Otros consejos

Aquí hay una versión terribles de fuerza bruta. Estoy seguro de que hay una manera mejor que esto, pero se debe trabajar de todos modos.

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

La parte triste de esto es que rápido binario a BCD conversiones están integradas en la arquitectura de microprocesadores x86, si se puede llegar a ellos!

Esta es una versión ligeramente más limpio entonces Jeffrey

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

solución Más común

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

He hecho una rutina genérica publicado en IntToByteArray que se puede utilizar como:

var yearInBytes = ConvertBigIntToBcd (2010, 2);

static byte[] IntToBCD(int input) { 
    byte[] bcd = new byte[] { 
        (byte)(input>> 8), 
        (byte)(input& 0x00FF) 
    };
    return bcd;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top