How can I extract a hex digit n from word x? - c

getHexDigit - Extract hex digit n from word x
Digits numbered from 0 (least significant) to 7 (most significant)
Examples: getHexDigit(0x12345678,2) = 0x6
Legal ops: ! ~ & ^ | + << >>
I'm confused because I don't understand how to extract and write only using those ops. Please help!!
int getHexDigit(int x, int n) {
return (x >> (n >> 4)) & 0xff; // How do I fix this
}

A single digit corresponds to 4 bits, such that you have to shift n*4 bits right; So you have to multiply n by 4, and since you must not use n * 4, you can simply write n << 2; shifting two bits left means 2*2:
return (x >> (n << 2)) & 0x0F;
Then you have to "unmask" all the digits except the one you want to have; Therefore the & 0x0F.

This should do it:
int getHexDigit(int x, int n) {
return (x >> (n << 2)) & 0xf;
}
First, multiply n by 4 (by shifting left by 2-bits) because each hex digit is 4 bits, and then just take that group out by shifting right and masking with 0x0f.
For example, see how it works for getHexDigit(0x1234, 2):
bit pos 1 1 1 1 1 1
5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
(val) 1 2 3 4
x = 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0
n = 2
n << 2 = 4
(val) 0 1 2 3
x >> 4 = 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1
(val) 0 0 0 3
(x >> 4) & 0x0f = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1

Related

How can i find all combinations of K elements of a given set of N elemets without a recursion?

I tried to program something in C but it goes too deep for me…
I have studied a relevant paper "A CONTROL STRUCTURE FOR A VARIABLE NUMBER OF NESTED LOOPS, Skordalakis, Papakonstantinou", I have tried to transfer the flow chart proposed in C, but it is not possible with structured programming. The idea should be something like:
b1 = 1;
for (m = 1 ; m <= K ; m++) {
for (i[m] = b[m] ; i[m] <= n; i[m]++) {
if ( m < K ) {
a[m] = i[m];
b[m+1] = i[m] + 1;
break;
}
a[m] = i[m];
if ( i[m] < n ){
i[m] = i[m] + 1;
m = m - 1;
continue;
}
}
}
i is the control variable for every loop (an array), b is the starting parameter for every loop (an array again) and the a array holds every combination.
I have seen some solutions to similar problems that they use a boolean flow control variable (also proposed in the paper).
Can somebody advise?
Here is one possible solution that just occured to me.
Given a set of n elements, we can represent a choice of k elements as a binary number.
For example, with n=6 and k=2, we could choose the second and last elements:
010001
We could just enumerate the binary numbers of n digits, and discard the ones that don't have exactly k ones.
For example, with n=4 and k=2.
0000
0001
0010
0011 ✓
0100
0101 ✓
0110 ✓
0111
1000
1001 ✓
1010 ✓
1011
1100 ✓
1101
1111
But that's too many wasted iterations.
So I thought about making a sequence that generates only the numbers with exacly k ones.
For Example, with n=6 and k=3, I would enumaterate as follows:
1 1 1 0 0 0
1 1 0 1 0 0
1 0 1 1 0 0
0 1 1 1 0 0
1 1 0 0 1 0
1 0 1 0 1 0
0 1 1 0 1 0
1 0 0 1 1 0
0 1 0 1 1 0
0 0 1 1 1 0
1 1 0 0 0 1
1 0 1 0 0 1
0 1 1 0 0 1
1 0 0 1 0 1
0 1 0 1 0 1
0 0 1 1 0 1
1 0 0 0 1 1
0 1 0 0 1 1
0 0 1 0 1 1
0 0 0 1 1 1
If you take some time to think about it, you will start to understand how the algorithm would work.
We initialize the array with all the(k) ones at the beginning. We are shifting them to the end in some way, and we keep going until all the ones are at the end.
Try to implement that yourself without looking at the solution: https://ideone.com/aY9YBl

Bit Expansion with finite width (Expanding PBM Images) in C

I am trying to expand a PBM image of say, 5x5 to 10x10 but I have hit somewhat of a road block.
I have read the header, and height / width with the following
int fSize = size(inFile);
char *inputBuffer = malloc(fSize);
int pbmHeight, pbmWidth;
memset(inputBuffer, 0, fSize);
if (!fgets(inputBuffer, sizeof(inputBuffer), inFile)) {
fprintf(stderr, "Unable to read image format.\n");
exit(-1);
}
if (inputBuffer[0] != 'P' || inputBuffer[1] != '4') {
fprintf(stderr, "Invalid image format.\n");
exit(-1);
}
if (fscanf(inFile, "%d %d", &pbmWidth, &pbmHeight) != 2) {
fprintf(stderr, "Invalid image size.\n");
exit(-1);
}
int i;
int bitRemainder = ((pbmWidth % 8) != 0 ? 8 - (pbmWidth % 8) : 0);
Then read the data
while (fgetc(inFile) != '\n');
fread(inputBuffer, pbmHeight * pbmWidth, 1, inFile);
I have a second char *secondPBM which contains another PBM image of the same height / width
What I am looking to do, is iterate through each bit of the 1st image, the 2nd image, compare, and then output specific bits to an output
For example, here is image 1 (Note the image width is 5, but it needs to fill 1 byte)
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Here is image 2
1 1 1 1 1 0 0 0
1 1 1 1 1 0 0 0
1 1 1 1 1 0 0 0
1 1 1 1 1 0 0 0
1 1 1 1 1 0 0 0
Based on image 1, and image 2 bits I need to output 4 bits so the new image size becomes 2 * pbmWidth
So for example, the output should be (a 10x10 image, with 6 bits set to 0 to fill the remaining byte) (The bit values in the 2nd image will be set with another piece of code and and isn't exactly what is listed here)
1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0
0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0
1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0
0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0
1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0
0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0
1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0
0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0
1 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0
0 1 0 1 0 1 0 1 0 1 0 0 0 0 0 0
I'm reading the bit value of the 1st and 2nd image like this
Here are my getBitValue and setBitValue functions
int getBitVal(unsigned char *keyStrBin, int keyIndex) {
int keyMod = keyIndex % 8;
int keyIn = keyIndex / 8;
return (((keyStrBin[keyIn]) >> (7 - (keyMod))) & 1);
}
void setBitVal(unsigned char *keyC, int keyIndex) {
int keyMod = keyIndex % 8;
int keyIn = keyIndex / 8;
keyC[keyIn] |= (1 << (7 - (keyMod)));
}
int newWidth = 2 * pbmWidth;
int newHeight = 2 * pbmHeight;
int totalBits = newWidth * newHeight;
int newFileSize = (totalBits % 8 == 0) ? (totalBits / 8) : (totalBits / 8 + 1);
int bitRemainder = ((pbmWidth % 8) != 0 ? 8 - (pbmWidth % 8) : 0);
int newbitRemainder = ((newWidth % 8) != 0 ? 8 - (newWidth % 8) : 0);
for (i = 0; k = 0; i < newHeight * (newWidth + newbitRemainder); i++, k++) {
if (i != 0 && i % (pbmWidth - 1) == 0) {
i += (bitRemainder - 1);
}
if (k != 0 && k % (newWidth - 1) == 0) {
k += (newbitRemainder - 1);
}
if (getBitVal((unsigned char *)inputBuffer, i) == 0 && getBitVal(keyBuffer, k) == 0) {
// Code to set 1 bit to black in the 1st row, then set another bit to black in the 2nd row. For example, The bit at index 0 becomes a 1, then the bit at index 17 becomes a 1 (Making a 2x2 square)
// 1 0
// 0 1
// Then move on to the 2nd bit (or bit index 1) of the input image, compare.
}
else if (getBitVal((unsigned char *)inputBuffer, i) == 0 && getBitVal(keyBuffer, k) == 1) {
}
else if (getBitVal((unsigned char *)inputBuffer, i) == 1 && getBitVal(keyBuffer, k) == 0) {
}
else if (getBitVal((unsigned char *)inputBuffer, i) == 1 && getBitVal(keyBuffer, k) == 1) {
}
I can't seem to figure out how to set the bits in the comparative if statements.
I tried this, but it doesn't seem to work right.
setBitVal(pbmOut1Buffer, k * 2);
setBitVal(pbmOut1Buffer, (k * 2) + (newWidth + newbitRemainder) + 1);
Any help with this would be greatly appreciated. Thank you all in advance.

Matlab: vectorize assignment of values in matrix based on index

Apologies in advance if this question is a duplicate, or if the solution to this question is very straightforward in Matlab. I have a M x N matrix A, a 1 x M vector ind, and another vector val. For example,
A = zeros(6,5);
ind = [3 4 2 4 2 3];
val = [1 2 3];
I would like to vectorize the following code:
for i = 1 : size(A,1)
A(i, ind(i)-1 : ind(i)+1) = val;
end
>> A
A =
0 1 2 3 0
0 0 1 2 3
1 2 3 0 0
0 0 1 2 3
1 2 3 0 0
0 1 2 3 0
That is, for row i of A, I want to insert the vector val in a certain location, as specificied by the i'th entry of ind. What's the best way to do this in Matlab without a for loop?
It can be done using bsxfun's masking capability: build a mask telling where the values will be placed, and then fill those values in. In doing this, it's easier to work with columns instead of rows (because of Matlab's column major order), and transpose at the end.
The code below determines the minimum number of columns in the final A so that all values fit at the specified positions.
Your example applies a displacement of -1 with respect to ind. The code includes a generic displacement, which can be modified.
%// Data
ind = [3 4 2 4 2 3]; %// indices
val = [1 2 3]; %// values
d = -1; %// displacement for indices. -1 in your example
%// Let's go
n = numel(val);
m = numel(ind);
N = max(ind-1) + n + d; %// number of rows in A (rows before transposition)
mask = bsxfun(#ge, (1:N).', ind+d) & bsxfun(#le, (1:N).', ind+n-1+d); %// build mask
A = zeros(size(mask)); %/// define A with zeros
A(mask) = repmat(val(:), m, 1); %// fill in values as indicated by mask
A = A.'; %// transpose
Result in your example:
A =
0 1 2 3 0
0 0 1 2 3
1 2 3 0 0
0 0 1 2 3
1 2 3 0 0
0 1 2 3 0
Result with d = 0 (no displacement):
A =
0 0 1 2 3 0
0 0 0 1 2 3
0 1 2 3 0 0
0 0 0 1 2 3
0 1 2 3 0 0
0 0 1 2 3 0
If you can handle a bit of bsxfun overdose, here's one with bsxfun's adding capability -
N = numel(ind);
A(bsxfun(#plus,N*[-1:1]',(ind-1)*N + [1:N])) = repmat(val(:),1,N)
Sample run -
>> ind
ind =
3 4 2 4 2 3
>> val
val =
1 2 3
>> A = zeros(6,5);
>> N = numel(ind);
>> A(bsxfun(#plus,N*[-1:1]',(ind-1)*N + [1:N])) = repmat(val(:),1,N)
A =
0 1 2 3 0
0 0 1 2 3
1 2 3 0 0
0 0 1 2 3
1 2 3 0 0
0 1 2 3 0

C - Trouble with simple modulus table, it isn't so simple [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I've been crunching through Kernighan and Ritchie "The C Programming Language" and read that x mod y == x & y-1. So, I worked it out with pencil and paper, and worked fine, so then I tried to test it and here is the problem:
Code:
#include <stdio.h>
main()
{
int i, j;
for(i = 1; i < 10; i++){
for(j = 1; j < 10; j++)
printf("%3d",i & j-1);
printf("\n");
}
}
Gives the output:
0 1 0 1 0 1 0 1 0
0 0 2 2 0 0 2 2 0
0 1 2 3 0 1 2 3 0
0 0 0 0 4 4 4 4 0
0 1 0 1 4 5 4 5 0
0 0 2 2 4 4 6 6 0
0 1 2 3 4 5 6 7 0
0 0 0 0 0 0 0 0 8
0 1 0 1 0 1 0 1 8
and
#include <stdio.h>
main()
{
int i, j;
for(i = 1; i < 10; i++){
for(j = 1; j < 10; j++)
printf("%3d",i % j);
printf("\n");
}
}
gives the output:
0 1 1 1 1 1 1 1 1
0 0 2 2 2 2 2 2 2
0 1 0 3 3 3 3 3 3
0 0 1 0 4 4 4 4 4
0 1 2 1 0 5 5 5 5
0 0 0 2 1 0 6 6 6
0 1 1 3 2 1 0 7 7
0 0 2 0 3 2 1 0 8
0 1 0 1 4 3 2 1 0
Notice, the only change was the % that became &.
Any input would be much appreciated
The equation
x mod y == x & y-1
is only correct for y a power of 2.
If y = 2^k, the binary representaion of y is one 1-bit followed by k 0-bits (and preceded by a number of 0-bits depending on the width of the type), and the representation of y-1 is k 1-bits (preceded by 0s).
Then if you write x = q*y + r with 0 <= r < y, the binary representation of r needs at most k bits, and the last k bits of q*y are all 0, so the remainder of x modulo y consists of the least significant k bits of x, which are obtained by the bitwise and with y-1.
For an odd y > 1, y-1 is even, and so x & y-1 is always even, hence (y+1) % y == 1 != (y+1) & (y-1). For even y not a power of 2, replace 1 with the power of 2 corresponding to the lowest set bit of y in y+1.

convert decimal that is less than 1024 into two variable one with 8 bits and other with 2 using C

hi I'm programming a microcontroller using MikroC, and I have this variable which is less than 1024 (2^10bit) and I needed to convert that int value; to unsigned char value8bits; and put the least significant bits in the unsigned char value2bits;
I was actually thinking of using >> bit shifting don't know how yet? so what do you think ?
10bitvar = 956;
8bitvar = (10bitvar >> 2) & 0xff;
2bitvar = (10bitvar & 0x03);
10bitvar = 1 1 1 0 1 1 1 1 1 0
(10bitvar >> 2) = ? ? 1 1 1 0 1 1 1 1
& & & & & & & & &
0xff = 1 1 1 1 1 1 1 1
----------------
8bitvar 1 1 1 0 1 1 1 1
10bitvar = 1 1 1 0 1 1 1 1 1 0
& & & & & & & & &
0x03 = 0 0 0 0 0 0 1 1
----------------
2bitvar 0 0 0 0 0 0 1 0

Resources