Bit mask operation: what does the following code mean in C? - c

I am trying to debugging a piece of code at the moment and I could not figure it out what the following piece of code really does. Could anyone help me explain or give me ideas on the functionality of the following code?
uint8_t get_pca9955a_slave_loaded(uint8_t _slave)
{
uint8_t x = (uint8_t)(_slave / 16);
uint8_t y = (uint8_t)(_slave % 16);
uint16_t mask = 1U << y;
if (check_pca9955a_slave_valid(_slave)) {
return (uint8_t)((pca9955a_slaves_loaded[x] & mask) ? 1U : 0U);
} else {
return 0U;
}
}
Kind Regards,
Cheung

It unpacks a byte into its high nibble x and its low nibble y. Taking mod 16 is the same as taking the four lowest bits, and dividing by 16 is the same as taking the remaining bits.
It then uses y to calculate a bitmask and x as an offset into some kind of table of global variables that you didn’t share, checks that bit y is set in entry x or not, and returns either 1 or 0 in an unsigned byte.

Related

Swap first and last 5 bits in a 16-bit number

I have some C/C++ code where I have a 16-bit number (uint16_t), and I need to swap the first 5 bits with the last 5 bits, keeping their left-to-right order within each block of 5 bits. The middle 6 bits need to remain intact. I am not great at bitwise maths/operations so help would be appreciated!
Conceptually speaking, the switching of positions would look like:
ABCDEFGHIJKLMNOP becomes LMNOPFGHIJKABCDE
or more literally...
10101000000001010 becomes 0101000000010101.
Any help would be much appreciated!
First, you should check if whatever library you use doesn't have a RGB-BGR swap for R5G6B5 pixels already.
Here is a literal translation of what you wrote in your question. It is probably too slow for real-time video:
uint16_t rgbswap(uint16_t in) {
uint16_t r = (in >> 11) & 0b011111;
uint16_t g = (in >> 5) & 0b111111;
uint16_t b = (in >> 0) & 0b011111;
return b << 11 | g << 5 | r << 0;
}
Instead of breaking the input into 3 separate R, G and B components you can work on R and B in parallel by shifting to the higher bits
uint16_t rgb2bgr(uint16_t in)
{
uint16_t r0b = in & 0b1111100000011111;
uint16_t b0r = ((r0b << 22) | r0b) >> 11;
return b0r | (in & 0b11111100000);
}
Another alternative to use multiplication to swap R and B
uint16_t rgb2bgr_2(uint16_t in)
{
uint16_t r0b = in & 0b1111100000011111;
uint16_t b0r = r0b * 0b1000000000000000000000100000 >> 16;
return b0r | (in & 0b11111100000);
}
It's basically this technique which is useful for extracting bits or moving bits around
You can check the compiled result on Godbolt to see the multiplication method produces shorter output, but it's only useful if you have a fast multiplier

CRC-15 giving wrong values

I am trying to create a CRC-15 check in c and the output is never correct for each line of the file. I am trying to output the CRC for each line cumulatively next to each line. I use: #define POLYNOMIAL 0xA053 for the divisor and text for the dividend. I need to represent numbers as 32-bit unsigned integers. I have tried printing out the hex values to keep track and flipping different shifts around. However, I just can't seem to figure it out! I have a feeling it has something to do with the way I am padding things. Is there a flaw to my logic?
The CRC is to be represented in four hexadecimal numbers, that sequence will have four leading 0's. For example, it will look like 0000xxxx where the x's are the hexadecimal digits. The polynomial I use is 0xA053.
I thought about using a temp variable and do 4 16 bit chunks of code per line every XOR, however, I'm not quite sure how I could use shifts to accomplish this so I settled for a checksum of the letters on the line and then XORing that to try to calculate the CRC code.
I am testing my code using the following input and padding with . until the string is of length 504 because that is what the pad character needs to be via the requirements given:
"This is the lesson: never give in, never give in, never, never, never, never - in nothing, great or small, large or petty - never give in except to convictions of honor and good sense. Never yield to force; never yield to the apparently overwhelming might of the enemy."
The CRC of the first 64 char line ("This is the lesson: never give in, never give in, never, never,) is supposed to be 000015fa and I am getting bfe6ec00.
My logic:
In CRCCalculation I add each character to a 32-bit unsigned integer and after 64 (the length of one line) I send it into the XOR function.
If it the top bit is not 1, I shift the number to the left one
causing 0s to pad the right and loop around again.
If the top bit is 1, I XOR the dividend with the divisor and then shift the dividend to the left one.
After all calculations are done, I return the dividend shifted to the left four ( to add four zeros to the front) to the calculation function
Add result to the running total of the result
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#define POLYNOMIAL 0xA053
void crcCalculation(char *text, int length)
{
int i;
uint32_t dividend = atoi(text);
uint32_t result;
uint32_t sumText = 0;
// Calculate CRC
printf("\nCRC 15 calculation progress:\n");
i = length;
// padding
if(i < 504)
{
for(; i!=504; i++)
{
// printf("i is %d\n", i);
text[i] = '.';
}
}
// Try calculating by first line of crc by summing the values then calcuating, then add in the next line
for (i = 0; i < 504; i++)
{
if(i%64 == 0 && i != 0)
{
result = XOR(POLYNOMIAL, sumText);
printf(" - %x\n",result);
}
sumText +=(uint32_t)text[i];
printf("%c", text[i]);
}
printf("\n\nCRC15 result : %x\n", result);
}
uint32_t XOR(uint32_t divisor, uint32_t dividend)
{
uint32_t divRemainder = dividend;
uint32_t currentBit;
// Note: 4 16 bit chunks
for(currentBit = 32; currentBit > 0; --currentBit)
{
// if topbit is 1
if(divRemainder & 0x80)
{
//divRemainder = (divRemainder << 1) ^ divisor;
divRemainder ^= divisor;
printf("%x %x\n", divRemainder, divisor);
}
// else
// divisor = divisor >> 1;
divRemainder = (divRemainder << 1);
}
//return divRemainder; , have tried shifting to right and left, want to add 4 zeros to front so >>
//return divRemainder >> 4;
return divRemainder >> 4;
}
The first issue I see is the top bit check, it should be:
if(divRemainder & 0x8000)
The question doesn't state if the CRC is bit reflected (xor data into low order bits of CRC, right shift for cycle) or not (xor data into high order bits of CRC, left shift for cycle), so I can't offer help for the rest of the code.
The question doesn't state the initial value of CRC (0x0000 or 0x7fff), or if the CRC is post complemented.
The logic for a conventional CRC is:
xor a byte of data into the CRC (upper or lower bits)
cycle the CRC 8 times (or do a table lookup)
After generating the CRC for an entire message, the CRC can be appended to the message. If a CRC is generated for a message with the appended CRC and there are no errors, the CRC will be zero (or a constant value if the CRC is post complemented).
here is a typical CRC16, extracted from: <www8.cs.umu.se/~isak/snippets/crc-16.c>
#define POLY 0x8408
/*
// 16 12 5
// this is the CCITT CRC 16 polynomial X + X + X + 1.
// This works out to be 0x1021, but the way the algorithm works
// lets us use 0x8408 (the reverse of the bit pattern). The high
// bit is always assumed to be set, thus we only use 16 bits to
// represent the 17 bit value.
*/
unsigned short crc16(char *data_p, unsigned short length)
{
unsigned char i;
unsigned int data;
unsigned int crc = 0xffff;
if (length == 0)
return (~crc);
do
{
for (i=0, data=(unsigned int)0xff & *data_p++;
i < 8;
i++, data >>= 1)
{
if ((crc & 0x0001) ^ (data & 0x0001))
crc = (crc >> 1) ^ POLY;
else crc >>= 1;
}
} while (--length);
crc = ~crc;
data = crc;
crc = (crc << 8) | (data >> 8 & 0xff);
return (crc);
}
Since you want to calculate a CRC15 rather than a CRC16, the logic will be more complex as cannot work with whole bytes, so there will be a lot of bit shifting and ANDing to extract the desire 15 bits.
Note: the OP did not mention if the initial value of the CRC is 0x0000 or 0x7FFF, nor if the result is to be complemented, nor certain other criteria, so this posted code can only be a guide.

What is the mathematical meaning of swap high part and low part of a uint64_t?

The code is from an open source project of sha256,
uint64_t swapE64(uint64_t val) {
uint64_t x = val;
x = (x & 0xffffffff00000000) >> 32 | (x & 0x00000000ffffffff) << 32;
x = (x & 0xffff0000ffff0000) >> 16 | (x & 0x0000ffff0000ffff) << 16;
x = (x & 0xff00ff00ff00ff00) >> 8 | (x & 0x00ff00ff00ff00ff) << 8;
return x;
}
the function is not complex, but I don't know its mathematical means and usage.
My fault, I did't ask the question very clear. In different environments which use different endian representation, it is clear, this function will keep the data in a same meaning, but under the same endian representation, what does it means?
It absolutely will change the meaning of the data, or there is some other reason to swap it?
In the pseudocode for SHA256 on wikipedia it says
Pre-processing: append the bit '1' to the message append k bits '0',
where k is the minimum number >= 0 such that the resulting message
length (modulo 512 in bits) is 448. append length of message (without the '1' bit or padding), in bits, as 64-bit big-endian
integer
(this will make the entire post-processed length a multiple of 512 bits)
x86/x86_64 Linux and Unix are small endian.
It's converting the length of the message to big endian to add it to the end of the message, which it does in the source at L105 of sha256.c, and that section of the code is the only place where the swapE64 function is called:
https://github.com/noryb009/sha256/blob/77a185c837417ea3fc502289215738766a8f8046/sha256.c#L100

Fast way to know compute parity of bitvector

I am working with bitvectors in C. My bitvectors are unsigned long long's. For a large number of vectors I need to know if the parity, i.e. the number of bits that are 1, is even or odd.
The exact value is not important, just the parity. I was wondering if there is anything faster than calculating the number of ones and checking. I tried to think of something, but couldn't find anything.
A short example of how I want this to work:
void checkIntersection(unsigned long long int setA, unsigned long long int setB){
if(isEven(setA & setB)){
//do something
}
}
With divide and conquer technique:
uint64_t a = value;
a ^= (a >> 32); // Fold the 32 MSB over the 32 LSB
a ^= (a >> 16); // reducing the problem by 50%
a ^= (a >> 8); // <-- this can be a good break even point
..
return lookup_table[a & 0xff]; // 16 or 256 entries are typically good
..
Folding procedure can be applied until the end:
a ^= (a >> 1);
return a & 1;
In IA the Parity flag can be directly retrieved after the reduction to 8 bits.
a ^= (a >> 4); makes another good point to stop dividing, since some processor architectures can provide parallel Look Up Tables uint8_t LUT[16] embedded into XXM (or NEON) registers. Or simply the potential cache misses of 256-entry LUT's can simply overweight the computational task of one extra round. It's naturally best to measure which LUT size is optimal in a given architecture.
This last table consists actually of 16 bits only and can be emulated with the sequence:
return ((TRUTH_TABLE_FOR_PARITY) >> (a & 15)) & 1;
where bit N of the magic constant above encodes the boolean value for Parity(N).
You could precompute in an array the parity for all possible combinations of bits in a byte:
bool pre[256] = { 0, 1, 1, 0, 1, ....}
When you need to find out the parity of a larger array you just do:
bool parity (long long unsigned x)
{
bool parity = 0;
while(x)
{
parity ^= pre[x&0xff];
x>>=8;
}
return parity;
}
Disclaimer: I haven't tested the code, it's just an idea.
Pretty easy. Something like
unsigned population(unsigned long long x) {
x = ((x >> 1) & 0x5555555555555555) + (x & 0x5555555555555555);
x = ((x >> 2) & 0x3333333333333333) + (x & 0x3333333333333333);
x = ((x >> 4) & 0x0f0f0f0f0f0f0f0f) + (x & 0x0f0f0f0f0f0f0f0f);
x = (x >> 8) + x; // Don't need to mask, because 64 < 0xff
x = (x >> 16) + x;
x = (x >> 32) + x;
return x & 0xff;
}
should work. Also, some CPUs have population count instructions (I don’t think x86 does, mind).
If you like this kind of thing, you should check out the book Hacker’s Delight by Henry S. Warren, Jr.

Bit masking and separation in c

I am new to c programming and i need help in bit manipulation.
I would like to separate the number from a register which have encoded numbers in BCD.
for example;
the register got '29' as value two bits will denote 2 ='10' and four bits will denote 9='1001'.
It is an 8 bit register and rest bits are zero.
So shifting out the 4 bits will give me 2 at disposal.But what about getting the unit digit?
I need some help regarding that
I'm posting the code here:
#include<stdio.h>
main()
{
int x,y;
y=0x29;
x=y;
x=x>>4;
x=x*10;
printf("%d",x);
return(0);
}
You need to mask it out with binary 00001111, which is decimal 15 or hexadecimal 0x0f.
uint8_t reg = 41; // binary 00101001
uint8_t lo_nibble = (reg >> 0) & 0x0f;
uint8_t hi_nibble = (reg >> 4) & 0x0f;
To form a mask to capture the bottom n bits of a number, you can perform these steps (pen and paper at first, eventually in your head):
start with the value 1.
(1) // == 1 or 00000001
shift the value 1 up by n bits.
(1<<4) // == 16 or 00010000
subtract 1.
(1<<4)-1 // == 15 or 00001111
ANDing this mask with another value or variable will yield the bottom n bits of the number.
int in, hi, lo;
lo = in & ((1<<4)-1);
hi = (in>>4) & ((1<<4)-1);

Resources