简体   繁体   中英

How concatenate array of bytes and convert to decimal?

How can I concatenate bytes?, for example

I have one byte array, BYTE *buffer[2] = [0x00, 0x02], but I want concatenate this two bytes, but backwards.

something like that

0x0200 <---

and later convert those bytes in decimal 0x0200 = 512

but I don't know how do it on C, because I can't use memcpy or strcat for the reason that buffer is BYTE and not a CHAR, even don't know if I can do that

Can somebody help me with a code or how can I concatenate bytes to convert on decimal?

because I have another byte array, buff = {0x00, 0x00, 0x0C, 0x00, 0x00, 0x00} and need do the same.

help please. regards.

BYTE is not a standard type and is probably a typedef for unsigned char . Here, I'll use the definitions from <stdint.h> that define intgers for specified byte widths and where a byte is uint8_t .

Concatenating two bytes "backwards" is easy if you think about it:

uint8_t buffer[2] = {0x00, 0x02};
uint16_t x = buffer[1] * 256 + buffer[0];

It isn't called backwards, by the way, but Little Endian byte order. The opposite would be Big Endian, where the most significant byte comes first:

uint16_t x = buffer[0] * 256 + buffer[1];

Then, there's no such thing as "converting to decimal". Internally, all numbers are binary. You can print them as decimal numbers or as hexadeximal numbers or as numbers of any base or even as Roman numerals if you like, but it's still the same number:

printf("dec: %u\n", x);    // prints 512
printf("hex: %x\n", x);    // prints 200

Now let's look what happens for byte arrays of any length:

uint8_t buffer[4] = {0x11, 0x22, 0x33, 0x44};
uint32_t x = buffer[3] * 256 * 256 * 256
           + buffer[2] * 256 * 256 
           + buffer[1] * 256 
           + buffer[0];

See a pattern? You can rewrite this as:

uint32_t x = ( ( (buffer[3]) * 256 
                + buffer[2]) * 256 
                + buffer[1]) * 256 
                + buffer[0];

You can convert this logic to a function easily:

uint64_t int_little_endian(uint8_t *arr, size_t n)
{
    uint64_t res = 0ul;

    while (n--) res = res * 256 + arr[n];

    return res;
}

Likewise for Big Endian, wher you move "forward":

uint64_t int_big_endian(uint8_t *arr, size_t n)
{
    uint64_t res = 0ul;

    while (n--) res = res * 256 + *arr++;

    return res;
}

Lastly, code that deals with byte conversions usually doesn't use the arithmetic operations of multiplication and addition, but is uses so-called bit-wise operators. A multiplication with 2 is represented by a shifting all bits of a number right by one. (Much as a multiplication by 10 in decimal is done by shifting all digits by one and appending a zero.) Out multiplication by 256 will become a bit-shift of 8 bytes to the left, which i C notation is x << 8 .

Addition is done by applying the bit-wise or. These two operations are not identical, because the bit-wise or operates on bits and does not account for carry. In our case, where there are no clashes between additions, they behave the same. Your Little-Endian conversion function now looks like this:

uint64_t int_little_endian(uint8_t *arr, size_t n)
{
    uint64_t res = 0ul;

    while (n--) res = res << 8 | arr[n];

    return res;
}

And If that doesn't look like some nifty C code, I don't know. (If these bitwise operators confuse you, leave them for now. In your example, you're fine with multiplication and addition.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM