C# Byte[] to BCD and BCD to INT

A BCD number encodes a value from 0-9 into 4 bits. In packed BCD (probably what you're dealing with), a byte is used to contain two values 0-9, one in each nibble (4 bits) of the byte. To convert to an int, you have to do a little bit fiddling. For example, the following would convert an array of BCD bytes into an int, which can hold up to 9 digits. Use long if you have more than 9 bcd digit of input.

// assume byte[] bcds is input
int result = 0;
foreach(byte bcd in bcds) {
    result *= 100;
    result += (10 * (bcd >> 4));
    result += bcd & 0xf;
}

This assumes that each byte is stored as big-endian BCD, where the most significant digit is in the most significant nibble of the byte. This is what is described in the Wikipedia page for BCD as the more common implementation. If you are dealing with little-endian BCD, the conversion code within the for loop would be

    result *= 100;
    result += (10 * (bcd & 0xf));
    result += bcd >> 4;

You also need to ensure you have the correct endianness of your array, i.e., does the first byte in the array contain the most significant two digits, or the least significant two digits. For example, the number 123456 would fit into 3 bytes using packed BCD. Is 12 in byte[0] or byte[2]? You would need to adjust the loop above to reverse the order if your endianness is different than my assumption. I'm assuming 12 is in byte[0] (big endian, with the most significant digits in the leftmost byte).

As for the quantity described as BCD and decimal, I would need to see actual values to understand what they're talking about.


Each byte is two decimal digits, one in each nibble. If you show the bytes as hex, you can read the number easily.

0x08 0x27 0x42 0x17 0x75 = 827,421,775

You can get the high and low nibbles like this:

int high = currentByte >> 4;
int low = currentByte & 0xF;

Convert each byte into number like this:

int number = 10 * high + low;

But remember that each byte is 100 times bigger then the next byte.

With quantity having 3 decimal places, just divide the final number by 1,000 to get the actual value.


CORRECT code:

// assume byte[] bcds is input
int result = 0;
foreach(byte bcd in bcds) {
    result *= 100;
    result += (10 * (bcd >> 4));
    result += bcd & 0xf;
}

You can also create a custom extension to a byte[] by creating a public static class:

public static class BitConverterExtension
{
    public static UInt64 FromBCDToExtUInt64(this byte[] b, byte[] bcds, uint nBytes, uint startOf)
    {
        UInt64 result = 0;
        uint i = 0;

        for (i = 0; i < nBytes; i++)
        {
            result *= 100;
            result += (UInt64)(10 * (bcds[startOf + i] >> 4));
            result += (UInt64)(bcds[startOf + i] & 0xf);
        }

        return (result);

    }
}

i wrote this code and works for me:

 public uint BCD5ToInt(byte [] bcd)
{
uint outInt=0;

   for (int i = 0; i < bcd.Length; i++)
   {
       int mul = (int)Math.Pow(10,(i*2));
       outInt += (uint) (((bcd[i] & 0xF)) * mul);
       mul = (int)Math.Pow(10, (i * 2) + 1);
       outInt +=(uint)( ((bcd[i] >> 4) ) * mul);
   }

   return outInt;
}

This is reverse code:

  // Convert an unsigned integer into 5 bytes of 
    public byte[] IntToBCD5(uint numericvalue, int bytesize = 5)
    {
        byte[] bcd = new byte[bytesize];
        for (int byteNo = 0; byteNo < bytesize; ++byteNo)
            bcd[byteNo] = 0;
        for (int digit = 0; digit < bytesize * 2; ++digit)
        {
            uint hexpart = numericvalue % 10;
            bcd[digit / 2] |= (byte)(hexpart << ((digit % 2) * 4));
            numericvalue /= 10;
        }
        return bcd;
    }

And this is test code:

 public void test()
    {
        uint firstInt = 987654321;
        var array = IntToBCD5(firstInt);
        var outInt = BCD5ToInt(array);
        MessageBox.Show(outInt.ToString());
    }

My response might be a little bit late for the question but here is how I solved the question:

1- First I needed to find the length of the number e.g: 3422 -> 4, 100 -> 3

public static class NumbersUtility
{
    public static int FindNumberLength(int number)
    {
        return Convert.ToInt32( Math.Floor(Math.Log(number,10))+1);
    }

    public static int FindNumberDivisor(int number)
    {
        return Convert.ToInt32(Math.Pow(10, FindNumberLength(number)-1));
    }

    public static int[] FindNumberElements(int number)
    {
        int[] elements = new int[FindNumberLength(number)];
        int divisor = FindNumberDivisor(number);
        for (int i = 0; i < elements.Length; i++)
        {
            elements[i] = number/divisor;
            number %= divisor;
            divisor /= 10;
        }
        return elements;
    }
}

After that I have split the number into an array which makes it easier to traverse and process the number. There is one caveat though, if the number is of odd length then a zero has to be added to the beginning of the array.

       public static byte[] IntToBCD(int[] input, bool isLittleEndian = false)
    {
        byte[] outArr = new byte[Convert.ToInt32(Math.Ceiling((double) input.Length/2))];

        //Handle the case of an odd number in which a zero should be added at the beginning
        if (input.Length%2 != 0)
        {
            //Use a temp array to expand the old one, you can use lists or 
            //anyother datastructure if you wish to
            int[] newInput = new int[input.Length+1];
            Array.Copy(input,0,newInput,1,input.Length);
            newInput[0] = 0;
            input = newInput;
            //Dispose the temp array
            newInput = null;
        }

        for (int i = 0; i < outArr.Length; i++)
        {

            outArr[i]=(byte)(input[i*2]<<4);
            outArr[i]|=(byte)(input[i*2+1]);
        }
        return outArr;
    }

Comments

  1. Nguyen

    • 2017/8/9

    C is a powerful general-purpose programming language. It can be used to develop software like operating systems, databases, compilers, and so on.

  2. Braylen

    • 2016/10/2

    C (/ ˈ s iː /, as in the letter c) is a general-purpose, procedural computer programming language supporting structured programming, lexical variable scope, and recursion, with a static type system. By design, C provides constructs that map efficiently to typical machine instructions.

  3. Evan

    • 2019/10/4

    C programming is a general-purpose, procedural, imperative computer programming language developed in 1972 by Dennis M. Ritchie at the Bell Telephone 

  4. Aydin

    • 2021/7/1

    1 Day C -4.75% DJIA -2.19% S&P 500 -2.17% Financial Services -0.98% The Price to Earnings (P/E) ratio, a key valuation measure, is calculated by dividing the stock's most recent closing price by

  5. Nguyen

    • 2018/11/22

    learn-c.org is a free interactive C tutorial for people who want to learn C, fast.

  6. Reid

    • 2020/11/16

    Citigroup, Inc. Common Stock (C) Stock Quotes - Nasdaq offers stock quotes & market activity data for US and global markets.

  7. Robin

    • 2015/4/28

    Amazon.com: C Programming Language, 2nd Edition: 8601410794231: Brian W. Kernighan, Dennis M. Ritchie: Books.

  8. Salvatore

    • 2015/10/17

    Discover historical prices for C stock on Yahoo Finance. View daily, weekly or monthly format back to when Citigroup, Inc. stock was issued.

  9. Bianco

    • 2015/4/2

    The best site for C and C++ programming. Popular, beginner-friendly C and C++ tutorials to help you become an expert!

  10. Jax

    • 2016/6/8

    C or Do is the first note of the C major scale, the third note of the A minor scale (the relative minor of C major), and the fourth note (G, A, B, C) of the Guidonian hand, commonly pitched around 261.63 Hz.

  11. Uriel

    • 2015/7/2

    C++ (/ ˌ s iː ˌ p l ʌ s ˈ p l ʌ s /) is a general-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language, or "C with Classes".The language has expanded significantly over time, and modern C++ now has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.

  12. Yahya

    • 2021/3/14

    c = a + b; Here, ‘+’ is the operator known as addition operator and ‘a’ and ‘b’ are operands. The addition operator tells the compiler to add both of the operands ‘a’ and ‘b’. C/C++ has many built-in operator types and they are classified as follows:

Comments are closed.

Recent Posts