How can I simulate binary values using a vector of booleans in C++? - c++

I want to be able to retain the same amount of bits to my vector whilst still performing binary addition. For example.
int numOfBits = 4;
int myVecVal = 3;
vector< bool > myVec;
GetBinaryVector(&myVec,myVecVal, numOfBits);
and its output would be:
{0, 0, 1, 1}
I don't know how to make a function of GetBinaryVector though, any ideas?

This seems to work (although the article I added in initial comment seem to suggest you only have byte level access):
void GetBinaryVector(vector<bool> *v, int val, int bits) {
v->resize(bits);
for(int i = 0; i < bits; i++) {
(*v)[bits - 1 - i] = (val >> i) & 0x1;
}
}
The left hand side sets the i'th least significant bit which is index bits - 1 - i. The right hand side isolates the i'th least significant bit by bit shifting the value down i'th bit and masking everything but the least significant bit.
In your example val = 8, bits = 15. In the first iteration i = 0: we have (*v)[15 - 1 - 0] = (8 >> 0) & 0x1. 8 is binary 1000 and shifting it down 0 is 1000. 1000 & 0x1 is 0. Let's jump to i = 4: (*v)[15 - 1 - 4] = (8 >> 4) & 0x1. 1000 >> 4 is 1 and 1 & 0x1 is 1, so we set (*v)[10] = 1. The resulting vector is { 0, ..., 0, 1, 0, 0, 0 }

Related

Using bit wise operators

Am working on a C++ app in Windows platform. There's a unsigned char pointer that get's bytes in decimal format.
unsigned char array[160];
This will have values like this,
array[0] = 0
array[1] = 0
array[2] = 176
array[3] = 52
array[4] = 0
array[5] = 0
array[6] = 223
array[7] = 78
array[8] = 0
array[9] = 0
array[10] = 123
array[11] = 39
array[12] = 0
array[13] = 0
array[14] = 172
array[15] = 51
.......
........
.........
and so forth...
I need to take each block of 4 bytes and then calculate its decimal value.
So for eg., for the 1st 4 bytes the combined hex value is B034. Now i need to convert this to decimal and divide by 1000.
As you see, for each 4 byte block the 1st 2 bytes are always 0. So i can ignore those and then take the last 2 bytes of that block. So from above example, it's 176 & 52.
There're many ways of doing this, but i want to do it via using bit wise operators.
Below is what i tried, but it's not working. Basically am ignoring the 1st 2 bytes of every 4 byte block.
int index = 0
for (int i = 0 ; i <= 160; i++) {
index++;
index++;
float Val = ((Array[index]<<8)+Array[index+1])/1000.0f;
index++;
}
Since you're processing the array four-by-four, I recommend that you increment i by 4 in the for loop. You can also avoid confusion after dropping the unnecessary index variable - you have i in the loop and can use it directly, no?
Another thing: Prefer bitwise OR over arithmetic addition when you're trying to "concatenate" numbers, although their outcome is identical.
for (int i = 0 ; i <= 160; i += 4) {
float val = ((array[i + 2] << 8) | array[i + 3]) / 1000.0f;
}
First of all, i <= 160 is one iteration too many.
Second, your incrementation is wrong; for index, you have
Iteration 1:
1, 2, 3
And you're combining 2 and 3 - this is correct.
Iteration 2:
4, 5, 6
And you're combining 5 and 6 - should be 6 and 7.
Iteration 3:
7, 8, 9
And you're combining 8 and 9 - should be 10 and 11.
You need to increment four times per iteration, not three.
But I think it's simpler to start looping at the first index you're interested in - 2 - and increment by 4 (the "stride") directly:
for (int i = 2; i < 160; i += 4) {
float Val = ((Array[i]<<8)+Array[i+1])/1000.0f;
}

XOR programming puzzle advice

Given a long int x, count the number of values of a that satisfy the following conditions:
a XOR x > x
0 < a < x
where a and x are long integers and XOR is the bitwise XOR operator
How would you go about completing this problem?
I should also mentioned that the input x can be as large as 10^10
I have managed to get a brute force solution by iterating over 0 to x checking the conditions and incrementing a count value.. however this is not an optimal solution...
This is the brute force that I tried. It works but is extremely slow for large values of x.
for(int i =0; i < x; i++)
{
if((0 < i && i < x) && (i ^ x) > x)
count++;
}
long long NumberOfA(long long x)
{
long long t = x <<1;
while(t^(t&-t)) t ^= (t&-t);
return t-++x;
}
long long x = 10000000000;
printf("%lld ==> %lld\n", 10LL, NumberOfA(10LL) );
printf("%lld ==> %lld\n", x, NumberOfA(x) );
Output
10 ==> 5
10000000000 ==> 7179869183
Link to IDEOne Code
Trying to explain the logic (using example 10, or 1010b)
Shift x to the left 1. (Value 20 or 10100b)
Turn off all low bits, leaving just the high bit (Value 16 or 10000b)
Subtract x+1 (16 - 11 == 5)
Attempting to explain
(although its not easy)
Your rule is that a ^ x must be bigger than x, but that you cannot add extra bits to a or x.
(If you start with a 4-bit value, you can only use 4-bits)
The biggest possible value for a number in N-bits is 2^n -1.
(eg. 4-bit number, 2^4-1 == 15)
Lets call this number B.
Between your value x and B (inclusive), there are B-x possible values.
(back to my example, 10. Between 15 and 10, there are 5 possible values: 11, 12, 13, 14, 15)
In my code, t is x << 1, then with all the low bits turned off.
(10 << 1 is 20; turn off all the low bits to get 16)
Then 16 - 1 is B, and B - x is your answer:
(t - 1 - x, is the same as t - ++x, is the answer)
One way to look at this is to consider each bit in x.
If it's 1, then flipping it will yield a smaller number.
If it's 0, then flipping it will yield a larger number, and we should count it - and also all the combinations of bits to the right. That conveniently adds up to the mask value.
long f(long const x)
{
// only positive x can have non-zero result
if (x <= 0) return 0;
long count = 0;
// Iterate from LSB to MSB
for (long mask = 1; mask < x; mask <<= 1)
count += x & mask
? 0
: mask;
return count;
}
We might suspect a pattern here - it looks like we're just copying x and flipping its bits.
Let's confirm, using a minimal test program:
#include <cstdlib>
#include <iostream>
int main(int, char **argv)
{
while (*++argv)
std::cout << *argv << " -> " << f(std::atol(*argv)) << std::endl;
}
0 -> 0
1 -> 0
2 -> 1
3 -> 0
4 -> 3
5 -> 2
6 -> 1
7 -> 0
8 -> 7
9 -> 6
10 -> 5
11 -> 4
12 -> 3
13 -> 2
14 -> 1
15 -> 0
So all we have to do is 'smear' the value so that all the zero bits after the most-significant 1 are set, then xor with that:
long f(long const x)
{
if (x <= 0) return 0;
long mask = x;
while (mask & (mask+1))
mask |= mask+1;
return mask ^ x;
}
This is much faster, and still O(log n).

Can't understand this code?

Can anyone help me in understanding the following code:-
int r, countIt(int n) {
while (r += " 2 "[n % 10] & 3, n /= 10);
return r;
}
I found this code in one of the challenges of codefights.com, https://codefights.com/challenge/v5Zg8trjoun3PTxrZ/solutions/Aj3ppbhSShixt4nBi
This is a solution for counting number of holes in a number.
e.g.
1111 = 0
0000 = 4
1234 = 0
8888 = 8
I am not able to understand the following things:
1. Logic of this code
2. comma (,) operator used in return data type of the function
3. Use of []operator after string.
4. And actually the whole code.
Is that some kind of obfuscated C contest submission? Or code golf?
First, the weird declaration. It's just combining two unrelated declarations on one line. Just as
int x, y;
is equivalent to
int x;
int y;
so is your code equivalent to
int r;
int countIt(int n) {...}
It's a little known and, thankfully, little used quirk of the C grammar that you can do that.
The loop would become clearer if written this way:
do {
r += " 2 "[n % 10] & 3;
n /= 10;
} while (n);
It basically iterates over digits in the decimal representation of n.
Now the part of r += " 2 "[n % 10] & 3;. n % 10 is the low-order decimal digit of n. We use that as an index into a string literal (which is just an array of chars), then extract two low-order bits of the character's ASCII code and discard the rest. I'm pretty sure that, in the original program you copied this code from, the characters in that literal were not spaces, but rather certain unprintable characters chosen in such a way that the two low-order bits of their ASCII codes gave precisely the number of "holes" in the corresponding digit. 2 character is a red-herring - it's in position 12, but only characters 0 through 9 are actually used.
In other words, this part can be more clearly written this way:
static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
int digit = n % 10;
r += numHoles[digit];
Put together, we have:
int countIt(int n) {
// number of holes in digit 0 1 2 3 4 5 6 7 8 9
static const int numHoles[10] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
int r = 0;
do {
int digit = n % 10;
r += numHoles[digit];
n /= 10;
} while (n);
return r;
};
I looked up the link you provided. After carefully observing the code i came to following conclusion.
int r, countIt(int n) {.....}
is equivalent to writing as
int r;
int countIt(int n){.....}
now for
while (r += " 2 "[n % 10] & 3, n /= 10);
is equivalent to:
do{
r += " 2 "[n % 10] & 3;
n/=10;
}while(n);
Now comes the logical part of the code
r += " 2 "[n % 10] & 3;
let me give you some basics.
In c++
cout<<"abcde"[2];
will give you output
c
now if you watch carefully the code in link which you provided
its something like this:
r += " 2 "[n % 10] & 3;
is nothing but
r += "TAB,SPACE,SPACE,SPACE,SPACE,SPACE,TAB,SPACE,2,TAB"[n % 10] & 3;
Now its time to explain how this code is calculating number of holes.
The ASCII value of TAB is 9 whose binary equivalent is 1001.
The ASCII value of SPACE is 32 whose binary equivalent is 100000.
so bit wise anding TAB with 3 will result
1001 & 0011 = 0001 which is 1
bit wise anding SPACE with 3 will result
100000 & 000011 = 000000 which is 0
replacing TABs with 1 and SPACEs with 0 hence this concludes as writing
do{
r += "1000001021"[n % 10] & 3;
n/=10;
}while(n);
n % 10 is the low-order decimal digit of n. We use that as an index into a string literal, which contains information about how many holes is there in that low-order decimal digit then add it to result r.
Using special chars in browsers can be a problem, from Ascii Table we can use all chars that in octal ends in 0 to 2 or 4 to 6, using those 2 bits to know how many holes the number have (% 3 is the same as % 0b11, an and with the last 2 bits).
One solution with ascii chars is:
int countIt(int n) {
int r;
while (r += "1000101021"[n % 10] & 3, n /= 10);
return r;
}
Instead of "0" to "2", i could use something like this:
int countIt(int n) {
int r;
while (r += "! X0) I#*9"[n % 10] & 3, n /= 10);
return r;
}
I don't know what chars he tried to use, but didn't work in the challenge website.

Efficient mapping from bits of one variable to another

I have 4 x Uint32 variables named lowLevelErrors1, lowLevelErrors2... up to 4. Each bit on those represent a low level error. I need to map them to a Uint64 variable named userErrors. Each bit of the userError represent an error shown to the user which can be set due to 1 or more low level errors. In other words, every low level error is mapped to 1 user error. 2 or more low level errors can be mapped to the same user error.
Let's scale it down to 2x Uint8 low level errors and 1x Uint8 user error so we can see an example.
Example: If any of the following low level errors is set {ERR_VOLT_LOW || ERR_NO_BATTERY || ERR_NOT_CHARGING} (which correspond to bit 0, bit 2 and bit 3 of lowLevelErrors1) then the user error US_ERR_POWER_FAIL is set (which is bit 5 of userErrors).
So the only way I could think of was to have a map array for each lowLevelErrors variable that will be used to map to the corresponding bit of the userErrors.
/* Let's say the lowLevelErrors have to be mapped like this:
lowLevelErrors1 bit maps to userError bit
0 5
1 1
2 5
3 5
4 0
5 2
6 7
7 0
lowLevelErrors2 bits maps to userError bit
0 1
1 1
2 0
3 3
4 6
5 6
6 4
7 7
*/
Uint8 lowLevelErrors1 = 0;
Uint8 lowLevelErrors2 = 0;
Uint8 userErrors = 0;
Uint8 mapLLE1[8] = {5, 1, 5, 5, 0, 2, 7, 0};
Uint8 mapLLE2[8] = {1, 1, 0, 3, 6, 6, 4, 7};
void mapErrors(void)
{
for (Uint8 bitIndex = 0; bitIndex < 8; i++)
{
if (lowLevelErrors1 && (1 << i)) //If error bit is set
{
userErrors |= 1 << mapLLE1[bitIndex]; //Set the corresponding user error
}
}
for (Uint8 bitIndex = 0; bitIndex < 8; i++)
{
if (lowLevelErrors2 && (1 << i)) //If error bit is set
{
userErrors |= 1 << mapLLE2[bitIndex]; //Set the corresponding user error
}
}
}
The problem with this implementation is the need for the map arrays. I will need to have 4x uint8 array[32] = 128 uint8 variables and we are running low on memory on the microcontroller.
Is there any other way to implement the same functionality using less RAM?
You have 128 input bits, each of which is mapped to a bit number from 0 to 63. So that is 128 * 6 = 768 bits of information, which needs at least 96 bytes of storage unless there is some regular pattern to it.
So you need at least 96 bytes; and even then, it would be stored as packed 6-bit integers. The code to unpack these integers might well cost more than the 32 bytes that you save by packing them.
So you basically have three choices: a 128-byte array, as you suggest; packed 6-byte integers; or some regular assignment of the error codes that is easier to unpack (which is not a possibility if the specific error code mapping is fixed).
Since you haven't given a complete example with ALL errors, it's hard to say what is the "best" method, but I would construct a table of "mask" and "value":
Something like this:
struct Translate
{
uint32_t mask;
// Maybe have mask[4]?
uint64_t value;
};
// If not mask[4], the
Translate table[] =
{
{ ERR_VOLT_LOW | ERR_NO_BATTERY | ERR_NOT_CHARGING,
// If mask[4] then add 3 more values here - expect typically zeros
US_ERR_POWER_FAIL },
...
};
I'm not sure which will make more sense, to have 4 different values in the table, or have 4 different tables - it would depend on how often your errors from LowLevel1 and LowLevel2, LowLevel2 and LowLevel4, etc are mapping to the same error. But by storing a map of multiple errors to one value, you should.
Now, once we have a data structure, the code becomes something like:
for(auto a : table)
{
if (a.mask & lowLevelErrors1)
{
userErrror |= a.value;
}
}

C++ using AND operator in integer expression

I'm reading some source code for designing an Octree and found this in the code. I have removed some elements for simplication, but can anyone explain what i&4 is supposed to evaluate to?
for (int i = 0; i < 8; i++)
{
float j = i&4 ? .5f : -.5f;
}
& is the bitwise AND Operator.
It just does a bitwise operation of the value stored in i AND 0x4.
It exactly just isolates the third bit as 2^2 = 4.
Your expression in the loop checks if third bit is set in i and assigns to j (which must be a float!) 0.5 or if not set -0.5
I am not sure, but it may evaluate the bitwise and operation of i and 4 (100), so any number which has a '1' in its third bit will be evaluted to true, otherwise false.
Ex:
5 (101) & 4 (100) = 100 (4) which is different from 0 so its true
8 (1000) & 4 (100) = 0000 (0) which is false
The & operator in this case is a bitwise AND. Since the second operand is 4, a power of 2, it evaluates to 4 when i has its second least-significant bit set, and to 0 otherwise.
The for loop takes i from 0 to 7, inclusive. Consider bit representations of i in this range:
0000 - 0
0001 - 1
0010 - 2
0011 - 3
0100 - 4
0101 - 5
0110 - 6
0111 - 7
^
|
This bit determines the result of i & 4
Therefore, the end result of the conditional is as follows: if the second bit is set (i.e. when i is 4, 5, 6, or 7), the result is 0.5f; otherwise, it is -0.5f.
For the given range of values, this expression can be rewritten as
float j = (i >= 4) ? .5f : -.5f;
i & 4 just evaluate to true when the value-4 bit is set. In your case this only happens in the second half of the loop. So the code could actually be rewritten:
for (int i = 0; i < 4; i++)
{
float j = -.5f;
}
for (int i = 4; i < 8; i++)
{
float j = .5f;
}