General method for constructing bitwise expressions satisfying constraints/with certain values? - bit-manipulation

Say I'm looking for a bitwise function to have certain values, for instance -
f(0b00,0b00)!=0
f(0b00,0b10)==0
f(0b10,0b10)!=0
f(0b11,0b10)!=0
f(0b01,0b10)==0
Is there a general method for constructing a single bitwise expression f for such systems? (I don't know for sure, but think there might be crappy solutions possible if you have gigantic expressions masking out one bit at a time, so let's say that the expressions have to work for all sizes of ints)
The best I've been able to do to convert the above is
f(int a, int b)
{
if (a==0 ) {
return b==0;
} else {
return (a&b)!=0;
}
}
I have a suspicion that it's difficult to combine (x==0) conditions with (x!=0) conditions (given x, is there a bitwise function f such that x==0 <=> f(x)!=0? ), but i don't know how much of an impediment that is here.
Any answers would be poured over with great interest :)
Peace,
S

The most general construction is an extended version of "minterms". Use bitwise operators to construct a predicate that is -1 iff the input matches a specific thing, AND the predicate with whatever you want the result to be, then OR all those things together. That leads to horrible expressions of course, possibly of exponential size.
Using arithmetic right shifts, you can construct a predicate p(x, c) = x == c:
p(x, c) = ~(((x ^ c) >> 31) | (-(x ^ c) >> 31))
Replace 31 by the size of an int minus one.
The only number such that it and its negation are both non-negative, is zero. So the thing inside the final complement is only zero if x ^ c == 0, which is the same as saying that x == c.
So in this example, you would have:
(p(a, 0x00) & p(b, 0x00)) |
(p(a, 0x10) & p(b, 0x10)) |
(p(a, 0x11) & p(b, 0x10))
Just expand it.. into something horrible.
Obviously this construction usually doesn't give you anything sensible. But it's general.
In the specific example, you could do:
f(a, b) = (p(a, 0) & p(b, 0)) | ~p(a & b, 0)
Which can be simplified a little again (obviously the xors go away if c == 0, and two complements balance each other out).

Related

Is there a way to set up an app to solve equations and then compare them in C++?

I am trying to write a piece of code for my old Highschool teacher for a game he had us play literally called the "Dice Game." Let's just say that the game takes two d12's and multiplies them together to get a number (D) in this instance. Then you take 3 d6's and roll them to get your A, B, and C variables. You would then either Add, Subtract, Multiply, Divide, Exponentiate, or Root by that number to get as close to as you could to D. Those operations would stand for x and y in the following equation
AxByC=D
I don't know how else to word this, but I am having trouble finding any way to solve these equations and then compare them. Maybe I am missing something simple, but I don't know.
EDIT: I should probably be more clear about the question. I know how to set all the equations up. It is just a matter of finding a way to compare the answers to the D variable and then the other answers to the equation to see which one is closer. The closest number to D wins, thus the whole point to the dice game.
If you are just trying to compare the answers to the D variable, why not loop through each equations result and compare them equal to D?
for (int i = 0; i < equationResults.size(); i++) {
if (equationResults[i] == D)
return true;
}
EDIT: If you are trying to find the closest to D, you can compare each answer to D and subtract the answer from D and store it, then return the min value:
closeToD[0] = D - equationResults[0];
return *min_element(closeToD.begin(), closeToD.end());
Since you can juggle the values around, as well as picking operators, you actually have two problems: generating the permutations of variables and generating the permutations of operators. The first part is rather straightforward:
std::array<int, 3> input;
std::sort(input.begin(), input.end());
do {
compute(input[0], input[1], input[2]);
} while (std::next_permutation(input.begin(), input.end()));
The compute part could be a function that takes such an array of 3 values and finds the best value, or closest to D, or just all values.
Generating all permutations of operators is slightly more annoying because next_permutation can't compare them, and also we accept duplicates. The easiest way is to just brute-force through them; I'll do it just for the slightly easier operators:
std::array<int, 16> compute(int a, int b, int c) {
return {
a + b + c,
a + b - c,
a + b * c,
a + b / c,
a - b + c,
a - b - c,
a - b * c,
a - b / c,
a * b + c,
a * b - c,
a * b * c,
a * b / c,
a / b + c,
a / b - c,
a / b * c,
a / b / c,
};
}
Generating such list of operations programmatically is a bit more challenging; you can't simply do (a op b) op c because of the aforementioned precedence. Doing it this way guarantees that the results are actually achievable because of the operator precedence built into the language.
This will still do redundant computations - e.g. in the first case, the result will be the same regardless of the permutation of a/b/c. Eliminating those is perhaps a more interesting exercise for later. Perhaps a small relief is the fact that if a == b or b == c, next_permutation will already take care of that for us, cutting the number of iterations from 6 to either 3 or 1.

How to write a C++ boolean function which uses n times the ternary condition statement?

I have a very simple question by I am very confused by the way I could implement this. I want to create a Boolean variable in a single line composed of ternary statement such as this:
boolean = a ? b : (c ? d : (e ? f : (g ? i : j );
It is working for 1, 2 or 3 such imbricate conditions for the purposes of my codes but I which to write it in a way that I could choose how many such ternary conditions I want to put into each other to define the Boolean variable.
And I am stuck with this because at the end it looks like I cannot add the last condition. I have tried to think of a recursive function, maybe with some counter, but I could not manage to write it. I do not know if what I ask is simpler or clear.
The condition are not fully independent of each other, there are intervals (coordinates in space) that follow each other somehow. So for example the 'a' in my example would be something like 11 and then it would continue when it is false with a new condition saying 22 and so on. Hence my idea of introducing some counter to put into the conditions.
But when I arrive at the last false condition, I don't know what to do because I cannot set up a random z>something to make my code work.
I am trying something like:
bool f(double x, double value, double z, double d, double n, double step, int &count);{
bool result;
count++;
if (count == n) {return result}
result = (x >=value+count*step && x<value+(count+1)*step) ? z>=d : f(x,value,z,d,n,step, &count);
}
So of course, besides probably many mistakes in the way I am writing recursive function since I never use them and do not use C or C++ usually, it will appear that in the last call of the function by itself, we will have something like a ? b : without the last parameter if the statement is false.
I tried to be as clear as I could. You can ask questions if you do not get the point. And any help is welcome, recursive functions, normal functions or a way to do it with no function at all...
Best regards and thanks in advance for your answers!
Edit:
The code with if should be something like:
if (a){
b}
else{
if (c){
d}
else{
if(e){
f}
else{
if(g){
I}
else{
j}
I may have forgotten some bracket but I hope it is understandable. And this point is to continue with, say n, if statements like this in a single line to create a Boolean variable and then being able to choose n instead of rewriting a new code each time I want to add an if statement.
EDIT about recursion:
Can someone explains me why this kind of function creates an infinite loop?
bool f(double x, double l, double z, double d, double step, int &count){
int n = (int)l/step;\\number of steps
count++;
if (count < n)
return (x >=l+count*step && x<l+(count+1)*step) ? z>=d*count : f(x,l,z,d,step,count);
else
return z>=d*(count-1);
}
I set the counter 'count' to -1 before calling the function and it seems to be the problem. It does the loop correctly but then it restarts again and again so that I cannot even check if my code makes any sense for my purpose. I thought after each return calling the function recursively, it would increase the counter but once it reaches n, it should return something else and go out of the function, not restart the counter and doing everything again...
To write that if ... else if ladder more clearly, get rid of the brackets and get rid of the indentation. Like this:
if (a)
boolean = b;
else if (c)
boolean = d;
and so on. But I’d be inclined to write it as a function:
if (a)
return b;
else if (c)
return d;
and so on. Still, if you like the ternary operator, it can be written in a disciplined way that is easily read:
boolean = a ? b
: c ? d
: e ? f
: g;
[4th version of the answer, taking into account comments]
In the particular case of the first simple example provided, it is possible to write a variadic function. Here the template ...args parameter indicates a variable number of parameters. One can call f(false,false,true) or f(false,false,false,true,true) or more parameters.
bool ff(bool a, bool b, bool c) {
return a ? b : c;
}
template<class ...Args>
bool ff(bool a, bool b, Args ...args){
return a ? b : ff(args...);
}
As user463035818 mentioned, there is a risk of short-circuiting in this first call of ff(.) function (by main), when all booleans are likely to be evaluated during this fist call. I don't know what would really happen with optimization by the compiler, with possible inlining and unrolling, but it is useless to stress the compiler.
Anyway I now understand that the number of steps is an input parameter, and a variadic template function does not seem to be applicable. It is certainly possible to solve it with a recursive function, similar to the one you proposed. However, in my opinion, a simple 'for loop' will be both efficient and flexible.
In my previous answer, I proposed a solution based on a for loop. However, as it does not correspond to your needs, because I misunderstood the mathematical problem, I removed it.
Instead, I come back to the second recursive function that you proposed in your post. You asked why the recursion did not finish. I could not comment it directly because of my poor reputation. As I did not see why the programme did not stop, I implemented it and the programme finished normally, but with a result that does not seem correct. I see a problem about parameter l. It seems to correspond both to a range for x and to a minimal value for x. I tried to correct it. It may happen that I did not select the input parameter values correctly . Therefore, I put the corresponding program hereafter for you to be able to check it.
#include <iostream>
bool f(double x, double xmin, double range, double z, double d, double step, int &count){
int n = range/step; //number of steps
count++;
if (count < n) {
double a = xmin + count*step;
return ((x >=a) && (x< a + step)) ? z>=d*count : f(x,xmin,range,z,d,step,count);
} else
return z>=d*(count-1);
}
int main () {
int count = -1;
double xmin = 0.0;
double x = 2.0;
double range = 4.0;
double step = 1.0;
double d = 1.0;
double z = 2.0;
bool test = f (x, xmin, range, z, d, step, count);
std::cout << "test = " << test << "\n";
std::cout << "count = " << count << "\n";
return 0;
}
In this particular case, it would be better to replace range by n as input parameter, to avoid redundant calculation of n.
Readability vs efficiency
The point is I don't want my code to be elegant or readable but efficient.
Honestly, I think this is not a good strategy. Inefficient code is not elegant. This does of course not imply that readable code is automatically efficient.
However, it is much easier to accidentally prevent the compiler doing an optimization rather than pushing it to emit better code than it already does anyhow. Readable code does contain less errors and helps you to avoid obvious inefficiencies. That being said,...
Why not to write a variadic conditional function?
Besides readability there is one more thing to consider: short-circuiting. With the plain conditional
bool x = condition ? t : some_other_function_call();
in case condition is true, then some_other_function_call() will not be evaluated, while in
bool x = foo(t,some_other_function_call());
the other function will be called in either case. You cannot get short-circuiting with foo.
What to do instead?
The answer by Pete Becker nicely demonstrates how to write the conditions in a clean way (most importantly you don't need to nest the cases when they are mutually exclusive (they are for the ternary!)).
Anyhow... how could a variadic conditional function be written?
Just for the sake of completeness, this is how you could write such a function to replace bool x = a ? b : (c ? d : (e ? f : (g ? i : j ); with a funciton call (please dont):
// DISCLAIMER: DONT DO THIS
bool my_conditional(std::vector<bool> x){
if (x.size() == 1) return *x.begin();
bool condition = *x.begin();
bool true_value = *(x.begin()+1);
return condition ? true_value : my_ternary({x.begin()+2,x.end()});
}
You could call it like this:
my_conditional({ condition1, true_value1, condition2, true_value2, false_value});
eg
std::cout << my_conditional({false,false,false,false,false});
prints 0.

Find initial value of a XOR list

I've a pool of numbers and from these one number X has been XORed with all the others. From these comparisons the minimum XOR values are stored in a list in a sorted format.
How can I retrieve X ?
e.g.
List: { 3, 2, 1, 0, 15, 14, 13, 12 }
Looking for X so that:
X ^ 3 < X ^ 2 < X ^ 1 <... < X ^ 12
Might not be only one X or even none X. Is there any way to revert the process of a XOR when we don't know the initial value and the result of it but just it's comparative values? How can this be solved efficiently given we know the whole pool of numbers?
You probably can't.
XOR is a really special operation. Its traits makes it impossible to figure out anything given only one of the operands, or the result.
If A xor B == C, then we have all the other five expressions:
C xor A == B
B xor C == A
C xor B == A
A xor C == B
B xor A == C
If you see this, you should know it's impossible to get one value from another. Two is always needed for the third one.
It depends very much on the outputs you have. The problem might be underconstrained, giving many possible X values. Or it might be impossible (no X satisfies the constraints).
One approach would be to pair values that differ only in the most-significant bit. If the smaller of each pair appears before the larger, the MSB must be 0; if the larger appears first, then the MSB must be 1.
With that knowledge, we can consider pairs that differ only in the first two bits, and so on.
If certain conditions were true in the output, the value of X could be determined fairly efficiently.
For example:
If the value 15 were in the output array, then you would know that X is a binary complement of one of the other numbers. Also, if the value 0 were in the output array, you would know that this was the result of X being XORed with itself.
A general algorithm with an efficient time complexity would be difficult, however.

What is the difference between if(x^1!=1) and if(int(x^1)!=1) in C++?

I am trying to find if x's first bit from right is 1, so I check if the value of x^1 is 1. However,
int x=6;
if (x^1!=1)
gives wrong answer, but
if (int(x^1)!=1)
gives the correct answer.
I am not sure why. Could someone clarify this for me?
It's a trap of operator precedence. Operator precedence determines how operations are "grouped" (like how 2*3+4 results in the 2*3 being "grouped" together). Adding parentheses changes how things are "grouped" (for example, 2*(3+4) causes 3+4 to be "grouped" together).
x^1!=1 is equivalent to x^(1!=1), which can be simplified to x^0.
int(x^1)!=1 is equivalent to (x^1)!=1 (because you've manually added parentheses here; the int part isn't very relevant; it's the parentheses that are important).
As you can see, x^(1!=1) and (x^1)!=1 are not the same.
If your goal is to check the first bit, I might suggest using a bitwise-AND (&). You can then just do if (x & 1) (but beware, mixing & and == will result in the same issues as you were having before, so use parentheses if you want to write if ((x & 1) == 1)).
Simply, != (Not equal relational operator) has high precedence than ^ (XOR bitwise operator). Check precedence
int x=6;
case 1: if (x^1!=1)
First, 1!=1 is 0; then 6^0= 6. (110 ^ 000 = 110); Check XOR table
Case 2: if (int (x^1)!=1)
First, x^1= 7; then 7!=1 is 1 (true).
#Cornstalks is right with his answer.
I just had that in mind ( it does'nt in fact answer your problem , but can make it more readable) :
Another approach for solving this problem is simply using the modulo operator:
if(x%2 == 0) // then first bit is 0
else // first bit is 1
In the end your task is simply a check for even or odd values.

Check if a bitset contains all values of another bitset

I'm trying to create an entity/component system that automatically matches suitable entities suitable systems. I'm using std::bitset and RTTI to automatically assign a bit value to every component type.
A system is defined like this: MovementSystem : System<Position, Velocity>.
MovementSystem, in this example, accepts any entity that has both the Position and the Velocity components (and any other component).
To check if an entity is suitable, I compare the system's bitset to the entity's bitset.
// Let's assume there are max 4 components
1 1 0 1 // Entity bitset
^ ^ ^
Position Velocity OtherB
1 1 0 0 // Suitable example system bitset
^ ^
Position Velocity
1 1 1 0 // Unsuitable example system bitset
^ ^ ^ // Entity does not have OtherA!
Position Velocity OtherA
So far, my solution is this one:
if(entityBitset & systemBitset) == systemBitset)) { /* entity is suitable! */ }
It seems to work, but I found it after doodling bitsets on a whiteboard. Is it correct? Can it be improved any further? (Entities will be created and destroyed an immense amount of times in my games, so performance is very important!)
Code is here if needed (shouldn't be), but it's almost impossible to read.
Your check
(a & b) == b; // check whether b is a subset of a
checks whether b is a subset of a, or equivalent, whether a contains/includes b. Note that you are creating one temporary followed by the break-early operator==.
This is equivalent to checking whether the difference of b and a is empty (note the order!)
(b & ~a).none();
This will be equally fast: a temporary followed by a break-early .none()
Given the interface of std::bitset, this is as fast you can get. The problem with std::bitset is that all its bitwise members (&, |, ^ and ~ loop over every word. The early termination operations like none(), any(), == or <, cannot be intertwined with them. This is because std::bitset does not expose the underyling word storage so you cannot perform the iteration yourself.
However, if you would write your own bitset class, you could write a special-purpose includes() algorithm that loops over each of the words, doing the & until you break-early
// test whether this includes other
bool YourBitSet::includes(YourBitSet const& other) const {
for (auto i = 0; i < NumWords; ++i)
if ((other.word[i] & ~(this->word[i])) != 0)
return false;
return true;
}
A similar algorithm missing from std::bitset would be intersects(), to efficiently test (a & b) != 0. Currently you have to first do bitwise and, and then the test for zero, whereas that would be more efficiently done in one loop. If std::bitset ever gets updated, it would be nice if they include includes() and intersects() primitives.