C code to convert endianness? - c

I want to convert an unsigned 32-bit integer as follows:
Input = 0xdeadbeef
Output = 0xfeebdaed
Thank you.

That's not an endianness conversion. The output should be 0xEFBEADDE, not 0xFEEBDAED. (Only the bytes are swapped, and each byte is 2 hexadecimal digits.)
For converting between little- and big-endian, take a look at _byteswap_ulong.

The general process for nibble reversal is:
((i & 0xF0000000)>>28) | ((i &
0xF000000)>>20) | ((i & 0xF00000)>>12)
| ..... | ((i & 0xF)<<28)
Mask, shift, or (I hope I got the numbers right):
Extract the portion of the number you're interested in by ANDing (&) with a mask.
Shift it to it's target location with the >> and << operations.
Construct the new value by ORing (|) the pieces together.
If you want to reorder bytes you will mask with 0xFF. As everyone is saying that's probably what you want and if you're looking for a canned version follow other people's suggestions.

Related

Reading two 8 bit registers into 12 bit value of an ADXL362 in C

I'm querying an ADXL362 Digital Output MEMS Accelerometer for its axis data which it holds as two 8 bit registers which combine to give a 12 bit value and I'm trying to figure out how to combine those values. I've never been good at bitwise manipulation so any help would be greatly appreciated. I would imagine it is something like this:
number = Z_data_H << 8 | Z_data_L;
number = (number & ~(1<<13)) | (0<<13);
number = (number & ~(1<<14)) | (0<<14);
number = (number & ~(1<<15)) | (0<<15);
number = (number & ~(1<<16)) | (0<<16);
ADXL362 data sheet (page 26)
Z axis data register
Your first line should be what you need:
int16_t number;
number = (Z_data_H << 8) | Z_data_L;
The sign-extension bits mean that you can read the value as if it was a 16-bit signed integer. The value will simply never be outside the range of a 12-bit integer. It's important that you leave those bits intact in order to handle negative values correctly.
You just have to do:
signed short number;
number = Z_data_H << 8 | Z_data_L;
The shift left by 8 bit combined with the lower bits you already
had figured out are combining the 2 bytes correctly. Just use the appropriate data size to have the C code recoginize the sign of the 12 bit number correctly.
Note that short not necessarily refers to a 16bit value, depending on your compiler and architecture - so, you might want to attempt to that.

Change 4 middle bits of a byte in C

I'm trying to change the 4 middle bits of a byte to correspond to the High nibble of another byte:
Suppose we start with:
In = 0bABCDEFGH
Out = 0bXXXXXXXX // Some random byte
I want:
Out = 0bXXABCDXX
Leaving whatever other bits were in Out's extremes unchanged.
How can I do this?
Note: The 'X' represents any bit, 0 or 1, just to distinguish what came from the input.
I got to:
(0b00111100 & (IN>>2)) = 0b00ABCD00
, which filters the high nibble and centers it but then what? How can I move it to Out?
simple:
out &= 0b11000011;
out |= (in >> 2 & 0b00111100);
out &= 0b11000011 sets out to 0bxx0000xx preserving 2 most significant bits and 2 least significant bits. in >> 2 shifts input by 2 giving us 0xYYABCDEF, YY could be 00 or 11 depending on what A is. To get rid of YY and EF we do & 0b00111100.
As pointed by #JB 0B is not standard notation, thus you should use something else, most preferably hex 0x notation. See this for more info.
Thus using hex this would be:
out &= 0xC3;
out |= (in >> 2 & 0x3C)
here is conversion table
`0xf` is `0b1111`
`0x3` is `0b0011`
`0xc` is `0b1100`
Assuming in and out are unsigned char, and that CHAR_BIT == 8:
out = (out & 0xC3) | ((in >> 2) & 0x3C);
i.e. 4 operations in total.
There are multiple alternatives. From a high-level perspective, you could
force the four middle bits of Out off, prepare a mask from In as show in your question, and combine Out and mask via bitwise OR (|)
force the four middle bits of Out off, prepare a mask from In as show in your question, and combine Out and mask via bitwise EXCLUSIVE OR (^)
force the four middle bits of Out on, prepare a mask from In similarly to how you do now, but with the outer bits on, and combine Out and mask via bitwise AND (&)
use a series of shifts, masks, and addition or bitwise OR operations to build up the wanted result section by section
Forcing bits off is achieved by bitwise AND with a mask that has 0s at (only) the positions you want to turn off.
Forcing bits on is achieved by bitwise OR with a mask that has 1s at (only) the positions you want to turn on.
You already seem to have a handle on shifting, though you do need to be careful there if you happen to be shifting objects of signed types. Prefer to use unsigned types for bit manipulation wherever possible.

How do you compare only certain bits in data type?

I'm trying to learn a bit about emulation and I'm trying to think of how I can decode opcodes. Each opcode is a short data type, 16 bits. I'd like to be able to compare only specific sets of 4 bits. For example: there are multiple opcodes that start with 00, such as 0x00E0.
I'd like to be able to compare each of these values in either bit or hexidecimal form. I was thinking maybe something along the lines of bit shifting to bump of everything else off so that the bits I don't care about would zero out. That may cause issues for the center bits and will require additional steps. What kind of solutions do you guys use for a problem like this?
Use a bit mask, which has the bits set that you care about. Then use the & operator to zero out everything that you don't care about. For instance, say we want to compare the lowest four bits in a and b:
uint16 mask = 0x000f;
if ((a & mask) == (b & mask)) {
// lowest 4 bits are equal
}
This is simple bit manipulation. You can mask the relevant bits with
int x = opcode & 0x00f0;
and compare the resulting value
if (x == 0x00e0) {
/* do something */
}
you can easily create the mask of "nbits" and and shift "pos" number of bits and do comparision
uint32_t mask = ~((~0) << nbits);
if( (num(mask << pos)) == 0x00e0 ) {
/* Do something */
}

How to handle multibyte numbers?

I'm trying to read binary data from a file. At the bytes 10-13 is a litte-endian binary-encoded number and I'm trying to parse it using only the information that the offset is 10 and the "size" is 4.
I've figured out I will have to do some binary shifting operations, but I'm not sure which byte goes where and how "far" and where it should be shifted.
If you know for certain the data is little endian, you can do something like:
int32 value = data[10] | (data[11] << 8) | (data[12] << 16) | (data[13] << 24);
This gives you a portable solution in case your code will run on both endian machines.

Explain this Function

Can someone explain to me the reason why someone would want use bitwise comparison?
example:
int f(int x) {
return x & (x-1);
}
int main(){
printf("F(10) = %d", f(10));
}
This is what I really want to know: "Why check for common set bits"
x is any positive number.
Bitwise operations are used for three reasons:
You can use the least possible space to store information
You can compare/modify an entire register (e.g. 32, 64, or 128 bits depending on your processor) in a single CPU instruction, usually taking a single clock cycle. That means you can do a lot of work (of certain types) blindingly fast compared to regular arithmetic.
It's cool, fun and interesting. Programmers like these things, and they can often be the differentiator when there is no difference between techniques in terms of efficiency/performance.
You can use this for all kinds of very handy things. For example, in my database I can store a lot of true/false information about my customers in a tiny space (a single byte can store 8 different true/false facts) and then use '&' operations to query their status:
Is my customer Male and Single and a Smoker?
if (customerFlags & (maleFlag | singleFlag | smokerFlag) ==
(maleFlag | singleFlag | smokerFlag))
Is my customer (any combination of) Male Or Single Or a Smoker?
if (customerFlags & (maleFlag | singleFlag | smokerFlag) != 0)
Is my customer not Male and not Single and not a Smoker)?
if (customerFlags & (maleFlag | singleFlag | smokerFlag) == 0)
Aside from just "checking for common bits", you can also do:
Certain arithmetic, e.g. value & 15 is a much faster equivalent of value % 16. This only works for certain numbers, but if you can use it, it can be a great optimisation.
Data packing/unpacking. e.g. a colour is often expressed as a 32-bit integer that contains Alpha, Red, Green and Blue byte values. The Red value might be extracted with an expression like red = (value >> 16) & 255; (shift the value down 16 bit positions and then carve off the bottom byte)
Data manipulation and swizzling. Some clever tricks can be achieved with bitwise operations. For example, swapping two integer values without needing to use a third temporary variable, or converting ARGB colour values into another format (e.g RGBA or BGRA)
The Ur-example is "testing if a number is even or odd":
unsigned int number = ...;
bool isOdd = (0 != (number & 1));
More complex uses include bitmasks (multiple boolean values in a single integer, each one taking up one bit of space) and encryption/hashing (which frequently involve bit shifting, XOR, etc.)
The example you've given is kinda odd, but I'll use bitwise comparisons all the time in embedded code.
I'll often have code that looks like the following:
volatile uint32_t *flags = 0x000A000;
bool flagA = *flags & 0x1;
bool flagB = *flags & 0x2;
bool flagC = *flags & 0x4;
It's not a bitwise comparison. It doesn't return a boolean.
Bitwise operators are used to read and modify individual bits of a number.
n & 0x8 // Peek at bit3
n |= 0x8 // Set bit3
n &= ~0x8 // Clear bit3
n ^= 0x8 // Toggle bit3
Bits are used in order to save space. 8 chars takes a lot more memory than 8 bits in a char.
The following example gets the range of an IP subnet using given an IP address of the subnet and the subnet mask of the subnet.
uint32_t mask = (((255 << 8) | 255) << 8) | 255) << 8) | 255;
uint32_t ip = (((192 << 8) | 168) << 8) | 3) << 8) | 4;
uint32_t first = ip & mask;
uint32_t last = ip | ~mask;
e.g. if you have a number of status flags in order to save space you may want to put each flag as a bit.
so x, if declared as a byte, would have 8 flags.
I think you mean bitwise combination (in your case a bitwise AND operation). This is a very common operation in those cases where the byte, word or dword value is handled as a collection of bits, eg status information, eg in SCADA or control programs.
Your example tests whether x has at most 1 bit set. f returns 0 if x is a power of 2 and non-zero if it is not.
Your particular example tests if two consecutive bits in the binary representation are 1.

Resources