How to make a word from Byte []? - c

I am new to programming world, I want to convert two bytes into a word.
So basically, I have a Byte array where index 0 is Buffer[0]=08 and index 1 is Buffer[1]=06
I want to create a word from these two bytes
where word ETHType to be 0x0806

You would use bitwise operators and bit shifting.
uint16_t result = ((uint16_t)Buffer[0] << 8) | Buffer[1];
This does the following:
The value of Buffer[0] is shifted 8 bits to the left. That gives you 0x0800
A bitwise OR is performed between the prior value and the value of Buffer[1]. This sets the low order 8 bits to Buffer[1], giving you 0x0806

word ETHType = 0;
ETHType = (Buffer[0] << 8) | Buffer[1];
edit: You should probably add a mask to each operation to make sure there is no bit overlap, and you can do it safely in one line.
word ETHType = (unsigned short)(((unsigned char)(Buffer[0] & 0xFF) << 8) | (unsigned char)(Buffer[1] & 0xFF)) & 0xFFFF;

Here's a macro I use for this very thing:
#include <stdint.h>
#define MAKE16(a8, b8) ((uint16_t)(((uint8_t)(((uint32_t)(a8)) & 0xff)) | ((uint16_t)((uint8_t)(((uint32_t)(b8)) & 0xff))) << 8))

Related

C set 3 bits for a particular number

I am trying to understand masking concept and want to set bits 24,25,26 of a uint32_t number in C.
example i have
uint32_t data =0;
I am taking an input from user of uint_8 which can be only be value 3 and 4 (011,100)
I want to set the value 011 or 110 in bits 24,25,26 of the data variable without disturbing other bits.
Thanks.
To set bits 24, 25, and 26 of an integer without modifying the other bits, you can use this pattern:
data = (data & ~((uint32_t)7 << 24)) | ((uint32_t)(newBitValues & 7) << 24);
The first & operation clears those three bits. Then we use another & operation to ensure we have a number between 0 and 7. Then we shift it to the left by 24 bits and use | to put those bits into the final result.
I have some uint32_t casts just to ensure that this code works properly on systems where int has fewer than 32 bits, but you probably won't need those unless you are programming embedded systems.
More general approach macro and function. Both are the same efficient as optimizing compilers do a really good job. Macro sets n bits of the d at position s to nd. Function has the same parameters order.
#define MASK(n) ((1ULL << n) - 1)
#define SMASK(n,s) (~(MASK(n) << s))
#define NEWDATA(d,n,s) (((d) & MASK(n)) << s)
#define SETBITS(d,nd,n,s) (((d) & SMASK(n,s)) | NEWDATA(nd,n,s))
uint32_t setBits(uint32_t data, uint32_t newBitValues, unsigned nbits, unsigned startbit)
{
uint32_t mask = (1UL << nbits) - 1;
uint32_t smask = ~(mask << startbit);
data = (data & smask) | ((newBitValues & mask) << startbit);
return data;
}

constructing 32 bit unsigned int in c

I am trying to construct a 32 bit binary value using an unsigned int. This is how
the 32 bit is split into parts
part 1 = 4 bit
part 2 = 2 bit
part 3 = 12 bit
part 4 = 2 bit
part 5 = 12 bit
How do i use the parts to construct 32 bit binary value (unsigned int) using
bit shifting can someone please help
(cant just shift bits... what if i want to update certain part?)
This is typical bit-shifting/bit-masking stuff. Here's how you set the initial value:
uint32_t value = ((part1 & 0xF) << 28)
| ((part2 & 0x3) << 26)
| ((part3 & 0xFFF) << 14)
| ((part4 & 0x3) << 12)
| (part5 & 0xFFF);
Each line uses a bitwise-AND (&) to clear the upper bits of each part so it doesn't overflow its allocated bit-width within the final value. For example, if part4 was 0xFF and you forgot the & 0x3 then the upper 6 bits of part4 (0xFC) would spill into the region for part3. Then the part is shifted (<<) to its final location and bitwise-OR'd (|) with the rest of the parts.
Some developers accomplish the same thing via bitfields but I don't recommend that approach due to potential portability issues.
Most (all?) of the other answers here so far have forgotten the bitwise-AND portion of the solution. Their answers will result in bugs if the part values ever exceed the specified bit width.
If you want to update a particular portion of the value, you'll need some more bit-masking via bitwise-AND and bitwise-OR. For example, to update part4 you'd do this:
value &= ~(0x3 << 12); /* Clear the part4 region */
value |= (part4 & 0x3) << 12; /* Set the part4 region to the new value */
That first line is a little tricky if you're new to bitwork in C. It says take 0x3 and shift it by 12 (result = 0x00003000), perform a bitwise-complement (result = 0xFFFFCFFF), and set value equal to itself bitwise-AND'd with that result. That's how you clear the part4 region of the value... because you're bitwise-AND'ing that region with zero the result is that region is now zero.
The second line sets the zeroed part4 region to the new value, just like we did above when setting the initial value.
You just use shifting, as you suggested:
uint32_t x = (part1 << 28)
| (part2 << 26)
| (part3 << 14)
| (part4 << 12)
| (part5);
Looks like you want this value:
part5 + (part4 << 12) + (part3 << 14) + (part2 << 26) + (part1 << 28)
(Make sure all five variables are of type uint32_t or some such.)

How to extract 2 bytes from a word, and how to make a word from 2 bytes (in C)?

I am trying to extract two bytes from a 16-bit word, and to make a 16-bit word from two bytes. This is what I have tried (byte = unsigned char, word = unsigned short):
Split grpix word into 2 bytes:
word grpix; // Assume that the value has been initialized
byte grpixl = grpix & 0x00FF;
byte grpixh = grpix & 0xFF00;
Make grpix word from 2 bytes
byte grpixh; // Assume that the value has been initialized
byte grpixl; // Assume that the value has been initialized
word grpix = grpixh;
grpix <<= 8;
grpix += grpixl;
For some reason, my code doesn't work as expected, and now I'm not sure if the "splitting" of the word is wrong, if the "making" of the word is wrong, or both... Could you give me some advice?
You're not shifting when you split the word. So if grpix is 0x1234, then grpixl gets the expected 0x34 but grpixh ends up as 0x1200. You should say
byte grpixh = grpix >> 8;
Of course, you're also ignoring any endianness concerns that may be present. You should probably convert your word to a known endian (with something like htons()) before attempting to split (and do the reverse conversion when joining).
Get to know: http://graphics.stanford.edu/~seander/bithacks.html for doing all manner of operations.
right_byte = short_val & 0xFF;
left_byte = ( short_val >> 8 ) & 0xFF
short_val = ( ( left_byte & 0xFF ) << 8 ) | ( right_byte & 0xFF );
I always do a &0xFF mask to assure I have no sign problems.
The simple code that I use to solve this, is:
word=(msb<<8)+lsb;
The following routines have proved very reliable for me:-
unsigned short get16int(a) char *a;{
unsigned short hi,lo;
hi = *a++ << 8;
lo = *a & 0x00ff; /* Needed to cater for sign extending when msb bit is set */
return (hi | lo);
}
put16int(a,i) char *a; int i;{
*a++ = i >> 8;
*a = i;
}
When you mask out the high byte, you need to also shift down by 8 bits, otherwise you just end up with a 16bit number with the bottom eight bits cleared.
byte grpixh = (grpix & 0xFF00) >> 8
Also your composition can be more efficient by using or-equals instead of plus-equals:
grpix |= grpixh << 8
word grpix = grpixl+256*grpixh;

32 bit hex in one variable

How can I put this hex 0x0a01 into a 32 bit var in C. What I'm trying to do is to parse a protocol. Part of the it has a length value. The problem is that I'm getting the received packet as an array, so the length 0x0a01 would be 0x0a on lets say [1] and 0x01 on [2], and I want them both to be 0a01 in one var so I can run a compare to a constant or use in a for loop.
ah 32 bit is a int in most current platforms (or int32_t defined in stdint.h)
and bit operations are made for this:
int var = buff[1]<<8|buff[2];
<< is the left shift so 0x0a gets transformed into 0x0a00 and | is the or operator so that is gets combined properly
uint32_t var;
char buff[128];
...
var = ((buff[1] & 0xFF) << 8) | (buff[2] & 0xFF);
Notice we use (buff[1] & 0xFF) << 8 and not buff[1] << 8, because if buff is a char array and char is signed, sign extension would occur on the promoted buff[1] when the value is negative.

is it possible to bit mask a char array

Let's say I have the following char array
char array[32];
I want to use only the 10 most significant bits of this array as a hash value.
Is it possible to use bitwise operation on this char array?
If so, how should i do it?
Assuming your implementation has 8-bit char, and that you have a 256-bit number stored in big endian in this array, here how to access the 10 msb of the 256-bit number.
uint16_t a;
a = (array[0] << 2 | (array[1] & 0xC0) >> 6) & 0x3FF;
I'm pretty sure you want something like this (again assuming 8-bit chars stored big endian in array):
uint16_t a = (((uint16_t)array[0] & 0xFF) << 2 | ((uint16_t)array[1] & 0xFF) >> 6) & 0x3FF;
To break that down a bit:
uint16_t byte0 = (uint16_t)array[0] & 0xFF;
uint16_t byte1 = (uint16_t)array[1] & 0xFF;
uint16_t a = (byte0 << 2 | byte1 >> 6) & 0x3FF;

Resources