I'm trying to make program that will for for example 273(000100010001b) make to 4095(111111111111b).
Funny part is that my program works for first 2 iterations, for example 17(00010001b) correctly returns 255(11111111b) but every byte after that doesn't work. For instance 273(000100010001b) returns 61951(1111000111111111b) and I cant figure out why is that.
Here is my code
int x,temp, i;
int mask = 15;
scanf_s("%d", &x);
temp = x;
for(i=0;i<4;i++){
mask<<=i*4;
if((temp&1)==1){
x|=mask;
} else{
}
temp>>=4;
}
printf("%d", x);
The issue is the shift you perform on mask. You shift it by 0 on the 1st iteration, 4 on the 2nd, 12 (4 + 8) on the 3rd and so on.
Also, you don't apply the mask over all the bits of temp. I can't tell if you do this on purpose.
Here you are a fixed version:
int foo(int x) {
/* ^ I didn't know how to call such function */
static size_t const mask_size = 4;
unsigned mask = 15;
int temp = x;
for (unsigned i = 0; i < (CHAR_BIT * sizeof(int)) / mask_size; ++i) {
if ((temp & 1) == 1) {
x |= mask;
}
mask <<= mask_size;
temp >>= mask_size;
}
return x;
}
My results are:
in: 17(10) = 10001(2)
out: 255(10) = 11111111(2)
in: 273(10) = 100010001(2)
out: 4095(10) = 111111111111(2)
in: 4369(10) = 1000100010001(2)
out: 65535(10) = 1111111111111111(2)
Related
Dear all C programmer:
X = 1 << N; (left shift)
how to recover N from X ?
Thanks
N in this case is the bit position where you shifted in a 1 at. Assuming that X here only got one bit set. Then to find out what number that bit position corresponds to, you have to iterate through the data and mask with bitwise AND:
for(size_t i=0; i<sizeof(X)*8; i++)
if(X & (1<<i))
printf("%d", i);
If performance is important, then you'd make a look-up table with all possible results instead.
In a while loop, keep shifting right until X==1, record how many times you have to shift right and the counter will give you N.
int var = X;
int count = 0;
while (var != 1){
var >>= 1;
count++;
}
printf("N is %d", count);
Try this (flsl from here which is available from string.h on macOS) :
int flsl(long mask)
{
int bit;
if (mask == 0) return (0);
for (bit = 1; mask != 1; bit++)
mask = (unsigned long)mask >> 1;
return (bit);
}
unsigned char binlog(long mask) { return mask ? flsl(mask) - 1 : 0; }
int x = 1 << 20;
printf("%d\n", binlog(x)); ===> 20
Very short, I am having issues understanding the workings of this code, it is much more efficient then my 20 or so lines to get the same outcome. I understand how left shift is supposed to work and the bitwise Or but would appreciate a little guidance to understand how the two come together to make the line in the for loop work.
Code is meant to take in an array of bits(bits) of a given size(count) and return the integer value of the bits.
unsigned binary_array_to_numbers(const unsigned *bits, size_t count) {
unsigned res = 0;
for (size_t i = 0; i < count; i++)
res = res << 1 | bits[i];
return res;
}
EDIT: As requested, My newbie solution that still passed all tests: Added is a sample of possible assignment to bits[]
unsigned binary_array_to_numbers(const unsigned *bits, size_t count)
{
int i, j = 0;
unsigned add = 0;
for (i = count - 1; i >= 0; i--){
if(bits[i] == 1){
if(j >= 1){
j = j * 2;
add = add + j;
}
else{
j++;
add = add + j;
}
}
else {
if( j>= 1){
j = j * 2;
}
else{
j++;
}
}
}
return add;
}
void main(){
const unsigned bits[] = {0,1,1,0};
size_t count = sizeof(bits)/sizeof(bits[0]);
binary_array_to_numbers(bits, count);
}
a breakdown:
every left shift operation on a binary number effectively multiplies
it by 2 0111(7) << 1 = 1110(14)
consider rhubarbdog answer - the operation can be seen as two separate actions. first left-shift (multiply by two) and then OR with the current bit being reviewed
the PC does not distinguish between the value displayed and the binary
representation of the number
lets try and review a case in-which your input is:
bits = {0, 1, 0, 1};
count = 4;
unsigned binary_array_to_numbers(const unsigned *bits, size_t count) {
unsigned res = 0;
for (size_t i = 0; i < count; i++)
res = res << 1 // (a)
res = res | bits[i]; /* (b) according to rhubarbdog answer */
return res;
}
iteration 0:
- bits[i] = 0;
- (a) res = b0; (left shift of 0)
- (b) res = b0; (bitwise OR with 0)
iteration 1:
- bits[i] = 1;
- (a) res = b0; (left shift of 0)
- (b) res = b1; (bitwise OR with 1)
iteration 2:
- bits[i] = 0;
- (a) res = b10; (left shift of 1 - decimal value is 2)
- (b) res = b10; (bitwise OR with 0)
iteration 3:
- bits[i] = 1;
- (a) res = b100; (left shift of 1 - decimal value is 4)
- (b) res = b101; (bitwise OR with 1)
the final result for res is binary(101) and decimal(5) as one would expect
NOTE: the use of unsigned is a must since a signed value will be interpreted as a negative value if the MSB is 1
hope that helps...
consider them as 2 operations i'll re-write res= ... as 2 lines
res = res << 1
res = res | 1
The firs pass res gets set to 1, next time it's shifted *2 then because it's now even +1
I'm trying to implement a FAT12 file system in which there's a FAT table data structure which is an unsigned char array. I need to write a function which given an array index would write a value to the next 12 bits (because it's FAT12) which is quite tricky because part of the value needs to go to one byte and the other part needs to go the half of the second byte.
This is the get value function I came up with:
//FAT is the unsigned char array
int GetFatEntry(int FATindex, unsigned char * FAT) {
unsigned int FATEntryCode; // The return value
// Calculate the offset of the WORD to get
int FatOffset = ((FATindex * 3) / 2);
if (FATindex % 2 == 1){ // If the index is odd
FATEntryCode = ((unsigned char)(&FAT[FatOffset])[0] + (((unsigned char)(&FAT[FatOffset])[1]) << 8));
FATEntryCode >>= 4; // Extract the high-order 12 bits
}
else{ // If the index is even
FATEntryCode = ((unsigned char)(&FAT[FatOffset])[0] + (((unsigned char)(&FAT[FatOffset])[1]) << 8));
FATEntryCode &= 0x0fff; // Extract the low-order 12 bits
}
return FATEntryCode;
}
I'm struggling to come up with the function which would set a value given a FATindex. I would appreciate any suggestions.
This seems to work. The data that should be written should be in the first 12 bits of data
void WriteFatEntry(int FATindex, unsigned char * FAT, unsigned char data[2]) {
// Calculate the offset of the WORD to get
int FatOffset = ((FATindex * 3) / 2);
unsigned char d;
if (FATindex % 2 != 0){ // If the index is odd
// Copy from data to d and e, and shift everything so that second half of
// e contains first half of data[1], and first half of e contains second
// half of data[0], while second half of d contains first half of data[0].
// First half of d contains a copy of first four bits in FAT[FatOffset]
// so that nothing changes when it gets written
unsigned char e=data[1];
e>>=4;
d=data[0];
e|=(d<<4) & 0b11110000;
d>>=4;
d |= FAT[FatOffset] & 0b11110000;
FAT[FatOffset]=d;
FAT[FatOffset+1] = e;
}
else{ // If the index is even
d = data[1] & 0b11110000;
d |= FAT[FatOffset+1] & 0b00001111;
FAT[FatOffset] = data[0];
FAT[FatOffset+1] = d;
}
}
#include <stdio.h>
#if 1 /* assuming MSB first */
#define MSB (idx)
#define LSB (idx+1)
#else /* assuming LSB first */
#define MSB (idx+1)
#define LSB (idx)
#endif
unsigned fat_getval(unsigned char * tab, unsigned num)
{
unsigned idx;
unsigned val;
idx = num + num/2;
val = (tab[MSB] <<8 ) + (tab[idx+1] ) ;
if (num %2 ==0) val >>= 4;
return val & 0xfff;
}
void fat_putval(unsigned char * tab, unsigned slot, unsigned val)
{
unsigned idx;
idx = slot + slot/2;
if (slot %2 ==0) { /* xyz_ */
val <<= 4;
val |= tab[LSB] & 0xf;
}
else { /* _xyz */
val |= (tab[MSB] & 0xf0) << 8;
}
tab[MSB] = val >>8;
tab[LSB] = val &0xff;
}
#undef MSB
#undef LSB
unsigned char fattable[] = "\x01\x23\x45\x67\x89\xab"; // 12 nibbles
int main(void)
{
unsigned idx, ret;
for (idx = 0; idx < 6; idx++) { // 6 bytes -> 12 nibbles */
printf(" %02x", fattable[idx] );
}
printf("\n");
printf("Put(0,0xabc):\n");
fat_putval(fattable, 0, 0xabc);
for (idx = 0; idx < 6; idx++) {
printf(" %02x", fattable[idx] );
}
printf("\n");
printf("Put(3,0xdef):\n");
fat_putval(fattable, 3, 0xdef);
for (idx = 0; idx < 6; idx++) {
printf(" %02x", fattable[idx] );
}
printf("\n");
printf("Get(0 to 4):\n");
for (idx = 0; idx < 4; idx++) { // 12 / 3 ~> 4 * 12bit entries
ret = fat_getval( fattable, idx);
printf("%u := %x\n", idx, ret );
}
printf("\n");
return 0;
}
This question already has answers here:
Count the number of set bits in a 32-bit integer
(65 answers)
Closed 9 years ago.
/*A value has even parity if it has an even number of 1 bits.
*A value has an odd parity if it has an odd number of 1 bits.
*For example, 0110 has even parity, and 1110 has odd parity.
*Return 1 iff x has even parity.
*/
int has_even_parity(unsigned int x) {
}
I'm not sure where to begin writing this function, I'm thinking that I loop through the value as an array and apply xor operations on them.
Would something like the following work? If not, what is the way to approach this?
int has_even_parity(unsigned int x) {
int i, result = x[0];
for (i = 0; i < 3; i++){
result = result ^ x[i + 1];
}
if (result == 0){
return 1;
}
else{
return 0;
}
}
Option #1 - iterate the bits in the "obvious" way, at O(number of bits):
int has_even_parity(unsigned int x)
{
int p = 1;
while (x)
{
p ^= x&1;
x >>= 1; // at each iteration, we shift the input one bit to the right
}
return p;
Option #2 - iterate only the bits that are set to 1, at O(number of 1s):
int has_even_parity(unsigned int x)
{
int p = 1;
while (x)
{
p ^= 1;
x &= x-1; // at each iteration, we set the least significant 1 to 0
}
return p;
}
Option #3 - use the SWAR algorithm for counting 1s, at O(log(number of bits)):
http://aggregate.org/MAGIC/#Population%20Count%20%28Ones%20Count%29
You can't access an integer as an array,
unsigned x = ...;
// x[0]; doesn't work
But you can use bitwise operations.
unsigned x = ...;
int n = ...;
int bit = (x >> n) & 1u; // Extract bit n, where bit 0 is the LSB
There is a clever way to do this, assuming 32-bit integers:
unsigned parity(unsigned x)
{
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}
I want to extract bits of a decimal number.
For example, 7 is binary 0111, and I want to get 0 1 1 1 all bits stored in bool. How can I do so?
OK, a loop is not a good option, can I do something else for this?
If you want the k-th bit of n, then do
(n & ( 1 << k )) >> k
Here we create a mask, apply the mask to n, and then right shift the masked value to get just the bit we want. We could write it out more fully as:
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
You can read more about bit-masking here.
Here is a program:
#include <stdio.h>
#include <stdlib.h>
int *get_bits(int n, int bitswanted){
int *bits = malloc(sizeof(int) * bitswanted);
int k;
for(k=0; k<bitswanted; k++){
int mask = 1 << k;
int masked_n = n & mask;
int thebit = masked_n >> k;
bits[k] = thebit;
}
return bits;
}
int main(){
int n=7;
int bitswanted = 5;
int *bits = get_bits(n, bitswanted);
printf("%d = ", n);
int i;
for(i=bitswanted-1; i>=0;i--){
printf("%d ", bits[i]);
}
printf("\n");
}
As requested, I decided to extend my comment on forefinger's answer to a full-fledged answer. Although his answer is correct, it is needlessly complex. Furthermore all current answers use signed ints to represent the values. This is dangerous, as right-shifting of negative values is implementation-defined (i.e. not portable) and left-shifting can lead to undefined behavior (see this question).
By right-shifting the desired bit into the least significant bit position, masking can be done with 1. No need to compute a new mask value for each bit.
(n >> k) & 1
As a complete program, computing (and subsequently printing) an array of single bit values:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
unsigned
input = 0b0111u,
n_bits = 4u,
*bits = (unsigned*)malloc(sizeof(unsigned) * n_bits),
bit = 0;
for(bit = 0; bit < n_bits; ++bit)
bits[bit] = (input >> bit) & 1;
for(bit = n_bits; bit--;)
printf("%u", bits[bit]);
printf("\n");
free(bits);
}
Assuming that you want to calculate all bits as in this case, and not a specific one, the loop can be further changed to
for(bit = 0; bit < n_bits; ++bit, input >>= 1)
bits[bit] = input & 1;
This modifies input in place and thereby allows the use of a constant width, single-bit shift, which may be more efficient on some architectures.
Here's one way to do it—there are many others:
bool b[4];
int v = 7; // number to dissect
for (int j = 0; j < 4; ++j)
b [j] = 0 != (v & (1 << j));
It is hard to understand why use of a loop is not desired, but it is easy enough to unroll the loop:
bool b[4];
int v = 7; // number to dissect
b [0] = 0 != (v & (1 << 0));
b [1] = 0 != (v & (1 << 1));
b [2] = 0 != (v & (1 << 2));
b [3] = 0 != (v & (1 << 3));
Or evaluating constant expressions in the last four statements:
b [0] = 0 != (v & 1);
b [1] = 0 != (v & 2);
b [2] = 0 != (v & 4);
b [3] = 0 != (v & 8);
Here's a very simple way to do it;
int main()
{
int s=7,l=1;
vector <bool> v;
v.clear();
while (l <= 4)
{
v.push_back(s%2);
s /= 2;
l++;
}
for (l=(v.size()-1); l >= 0; l--)
{
cout<<v[l]<<" ";
}
return 0;
}
Using std::bitset
int value = 123;
std::bitset<sizeof(int)> bits(value);
std::cout <<bits.to_string();
#prateek thank you for your help. I rewrote the function with comments for use in a program. Increase 8 for more bits (up to 32 for an integer).
std::vector <bool> bits_from_int (int integer) // discern which bits of PLC codes are true
{
std::vector <bool> bool_bits;
// continously divide the integer by 2, if there is no remainder, the bit is 1, else it's 0
for (int i = 0; i < 8; i++)
{
bool_bits.push_back (integer%2); // remainder of dividing by 2
integer /= 2; // integer equals itself divided by 2
}
return bool_bits;
}
#include <stdio.h>
int main(void)
{
int number = 7; /* signed */
int vbool[8 * sizeof(int)];
int i;
for (i = 0; i < 8 * sizeof(int); i++)
{
vbool[i] = number<<i < 0;
printf("%d", vbool[i]);
}
return 0;
}
If you don't want any loops, you'll have to write it out:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num = 7;
#if 0
bool arr[4] = { (num&1) ?true: false, (num&2) ?true: false, (num&4) ?true: false, (num&8) ?true: false };
#else
#define BTB(v,i) ((v) & (1u << (i))) ? true : false
bool arr[4] = { BTB(num,0), BTB(num,1), BTB(num,2), BTB(num,3)};
#undef BTB
#endif
printf("%d %d %d %d\n", arr[3], arr[2], arr[1], arr[0]);
return 0;
}
As demonstrated here, this also works in an initializer.