I am having the following enumeration:
typedef enum _options {
o1=1,
o2=2,
o3=4,
o4=8
} option;
Is it possible to have one function to check any combination of them, like (logically speaking):
o1 OR o2 OR o3
o1 AND o2
o1 AND (o2 OR o3)
(o1 OR o2) AND (o3 OR o4)
The following work for option=(o1|o2|o3) but not for option=((o1|o2) & (o3|o4))
BOOL doesMyValueHaveOption(option o) {
int v = myValue;
return (v & o);
}
Yes, but not like that. Observe the values of option that you get to see why - as soon as you AND together two sub-queries, everything goes wrong.
For arbitrary queries, you will need at least a list of options (each of which is also a combination), either in Sum Of Products or Product Of Sums form. That means you'd have to convert a query (which is really an expression tree) into one of those forms, which may result in exponential blowup. It may still be a reasonable approach though, depending on the structure of your typical query. If it really has to be general, you'd better just pass it as a tree (or maybe a DAG, you may as well share equal sub-trees).
If you go for the Product Of Sums form, your queries would look like (o1 OR o2 OR o4) AND (o2 OR o3 OR o5) AND (etc.., you'd pass a list {o1 | o2 | o4, o2 | o3 | o5, etc } and implement it as (not tested)
BOOL doesMyValueHaveAllOptions(vector<option> options) {
int v = myValue;
for (auto o : options)
if (!(v & o))
return false;
return true;
}
For Sum Of Products form, your queries would look like (o1 AND o3 AND o4) OR (o2 AND o4 AND o5) OR etc.., you'd pass a list {o1 | o3 | o4, o2 | o4 | o5, etc} note that while the o's are connected by "AND" in the query, they're combined with OR in the list (because otherwise it's just zero), and you could implement it as (not tested)
// todo: make up a better name
BOOL doesMyValueHaveAtLeastOneCombinationOfOptions(vector<option> options) {
int v = myValue;
for (auto o : options)
if ((v & o) != o)
return false;
return true;
}
Related
TL;DR
What's wrong with the last commented block of lines below?
// headers and definitions are in the down the question
int main() {
std::vector<int> v{10,20,30};
using type_of_temp = std::vector<std::pair<std::vector<int>,int>>;
// seems to work, I think it does work
auto temp = copy_range<type_of_temp>(v | indexed(0)
| transformed(complex_keep_index));
auto w = temp | transformed(distribute);
print(w);
// shows undefined behavior
//auto z = v | indexed(0)
// | transformed(complex_keep_index)
// | transformed(distribute);
//print(z);
}
Or, in other words, what makes piping v | indexed(0) into transformed(complex_keep_index) well defined, but piping v | indexed(0) | transformed(complex_keep_index) into transformed(distribute) undefined behavior?
Extended version
I have a container of things,
std::vector<int> v{10,20,30};
and I have a function which generates another container from each of those things,
// this is in general a computation of type
// T -> std::vector<U>
constexpr auto complex_comput = [](auto const& x){
return std::vector{x,x+1,x+2}; // in general the number of elements changes
};
so if I was to apply the complex_comput to v, I'd get,
{{10, 11, 12}, {20, 21, 22}, {30, 31, 32}}
and if I was to also concatenate the results, I'd finally get this:
{10, 11, 12, 20, 21, 22, 30, 31, 32}
However, I want to keep track of the index where each number came from, in a way that the result would encode something like this:
0 10
0 11
0 12
1 20
1 21
1 22
2 30
2 31
2 32
To accomplish this, I (eventually) came up with this solution, where I attempted to make use of ranges from Boost. Specifically I do the following:
use boost::adaptors::indexed to attach the index to each element of v
transform each resulting "pair" in a std::pair storing the index and result of the application of complex_comput to the value,
and finally transforming each std::pair<st::vector<int>,int> in a std::vector<std::pair<int,int>>.
However, I had to give up on the range between 2 and 3, using a helper "true" std::vector in between the two transformations.
#include <boost/range/adaptor/indexed.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <iostream>
#include <utility>
#include <vector>
using boost::adaptors::indexed;
using boost::adaptors::transformed;
using boost::copy_range;
constexpr auto complex_comput = [](auto const& x){
// this is in general a computation of type
// T -> std::vector<U>
return std::vector{x,x+1,x+2};
};
constexpr auto complex_keep_index = [](auto const& x){
return std::make_pair(complex_comput(x.value()), x.index());
};
constexpr auto distribute = [](auto const& pair){
return pair.first | transformed([n = pair.second](auto x){
return std::make_pair(x, n);
});
};
template<typename T>
void print(T const& w) {
for (auto const& elem : w) {
for (auto i : elem) {
std::cout << i.second << ':' << i.first << ' ';
}
std::cout << std::endl;
}
}
int main() {
std::vector<int> v{10,20,30};
using type_of_temp = std::vector<std::pair<std::vector<int>,int>>;
auto temp = copy_range<type_of_temp>(v | indexed(0)
| transformed(complex_keep_index));
auto w = temp | transformed(distribute);
print(w);
//auto z = v | indexed(0)
// | transformed(complex_keep_index)
// | transformed(distribute);
//print(z);
}
Indeed, decommenting the lines defining and using z gives you a code that compiles but generates rubbish results, i.e. undefined behavior. Note that applying copy_range<type_of_temp> to the first, working, range is necessary, otherwise the resulting code is essetially the same as the one on the right of auto z =.
Why do I have to do so? What are the details that makes the oneliner not work?
I partly understand the reason, and I'll list my understanding/thoughts in the following, but I'm asking this question to get a thorough explanation of all the details of this.
I understand that the undefined behavior I observe stems from z being a range whose defining a view on some temporary which has been destroyed;
given the working version of the code, it is apparent that temporary is v | indexed(0) | transformed(complex_keep_index);
however, isn't v | indexed(0) itself a temporary that is fed to transformed(complex_keep_index)?
Probably one important detail is that the expression v | indexed(0) is no more than a lazy range, which evaluates nothing, but just sets things up such that when one iterates on the range the computations is done; after all I can easily do v | indexed(0) | indexed(0) | indexed(0), which is well defined;
and also the whole v | indexed(0) | transformed(complex_keep_index) is well defined, otherwise the code above using w would probably misbehave (I know that UB doesn't mean that the result has to show something is wrong, and things could just look ok on this hardware, in this moment, and break tomorrow).
So there's something inherently wrong is passing an rvalue to transformed(distribute);
but what's wrong in doing so lies in distribute, not in transformed, because for instance changing distribute to [](auto x){ return x; } seems to be well defined.
So what's wrong with distribute? Here's the code
constexpr auto distribute = [](auto const& pair){
return pair.first | transformed([n = pair.second](auto x){
return std::make_pair(x, n);
});
};
What's the problem with it? The returned range (output of this transformed) will hold some iterators/pointers/references to pair.first which is part of goes out of scope when distribute returns, but pair is a reference to something in the caller, which keeps living, right?
However I know that even though a const reference (e.g. pair) can keep a temporary (e.g. the elements of v | indexed(0) | transformed(complex_keep_index)) alive, that doesn't mean that the temporary stays alive when that reference goes out of scope just because it is in turn referenced by something else (references/pointers/iterators in the output of transformed([n = …](…){ … })) which doesn't go out of scope.
I think/hope that probably the answer is already in what I've written above, however I need some help to streamline all of that so that I can understand it once and for all.
I just can't wrap my head around this.
Why do these two functions produce radically different results,
when line 4 seems identical?
Version I
int factorial(int val) // input=5; output=120
{
if (val != 0)
return factorial(val - 1) * val;
return 1;
}
Version II
int factorial(int val) // input=5; output=0
{
if (val != 0)
return factorial(--val) * val;
return 1;
}
They only seem identical if you don't read them - one says val - 1 and the other says --val.
val - 1: Subtraction. Evaluates to the value of val, minus one
--val: Decrement. Reduces val by one, and evaluates to the new value
The latter example has undefined behaviour because you try to read val again on the same line.
Version 2 changes the value of val via the --val, where version 1 only subtracts 1 from val but doesn't update the value of val when doing so.
Use of
return factorial(--val) * val;
is cause for undefined behavior. Don't use it.
For evaluating the expression, the compiler is free to evaluate factorial(--val) first, then evaluate val, and then perform the multiplication. It is also free to evaluate val first, then evaluate factorial(--val), and then perform the multiplication.
If the compiler chooses the first strategy, that statement is equivalent to:
--val;
return factorial(val)*val;
As you can see, that is incorrect.
If the compiler chooses the second strategy, that statement is equivalent to:
int res = factorial(val-1)*val;
--val
return res;
Had the compiler followed this strategy, you'd have gotten the correct answer.
OTOH, the statment
return factorial(val-1)*val;
does not suffer from that problem and always returns the correct value.
Is there any known way to compute the addition (and maybe the subtraction) of two Gray codes without having to convert the two Gray codes to regular binary, perform a binary addition then convert the result back to a Gray code? I managed to write increment and decrement functions, but the addition and subtraction seem even less documented and harder to write.
In this document under #6, there is an algorithm for serial Gray code addition (copied directly; note, that ⊕ is xor):
procedure add (n: integer; A,B:word; PA,PB:bit;
var S:word; var PS:bit; var CE, CF:bit);
var i: integer; E, F, T: bit;
begin
E := PA; F := PB;
for i:= 0 to n-1 do begin {in parallel, using previous inputs}
S[i] := (E and F) ⊕ A[i] ⊕ B[i];
E := (E and (not F)) ⊕ A[i];
F := ((not E) and F) ⊕ B[i];
end;
CE := E; CF := F;
end;
This adds the Gray code words A and B to form the Gray code word S. The operand parities are PA and PB, the sum parity is PS. This propagates two carry bits internally, E and F, and produces two external carry bits CE and CF
Unfortunately, it doesn't state anything about subtraction, but I assume, when you can encode negative numbers, you can use addition for that.
I accepted #Sebastian Dressler's answer because the suggested algorithm indeed works. For the sake of completeness, I propose here a corresponding C99 implementation of the algorithm (C++ compatible):
// lhs and rhs are encoded as Gray codes
unsigned add_gray(unsigned lhs, unsigned rhs)
{
// e and f, initialized with the parity of lhs and rhs
// (0 means even, 1 means odd)
bool e = __builtin_parity(lhs);
bool f = __builtin_parity(rhs);
unsigned res = 0u;
for (unsigned i = 0u ; i < CHAR_BIT * sizeof(unsigned) ; ++i)
{
// Get the ith bit of rhs and lhs
bool lhs_i = (lhs >> i) & 1u;
bool rhs_i = (rhs >> i) & 1u;
// Copy e and f (see {in parallel} in the original paper)
bool e_cpy = e;
bool f_cpy = f;
// Set the ith bit of res
unsigned res_i = (e_cpy & f_cpy) ^ lhs_i ^ rhs_i;
res |= (res_i << i);
// Update e and f
e = (e_cpy & (!f_cpy)) ^ lhs_i;
f = ((!e_cpy) & f_cpy) ^ rhs_i;
}
return res;
}
Note: __builtin_parity is a compiler intrinsic (GCC and Clang) that returns the parity of the number of set bits in an integer (if the intrinsic does not exist, there are other methods to compute it by hand). A gray code is even when it has an even number of set bits. The algorithm can still be improved, but this implementation is rather faithful to the original algorithm. If you want details about an optimized implementation, you can have a look at this Q&A on Code Review.
I recently devised a new algorithm to add two Gray codes. Unfortunately, it is still slower than the naive double-conversion solution and is also slower than Harold Lucal's algorithm (the one in the accepted answer). But any new solution to a problem is welcome, right?
// lhs and rhs are encoded as Gray codes
unsigned add_gray(unsigned lhs, unsigned rhs)
{
// Highest power of 2 in lhs and rhs
unsigned lhs_base = hyperfloor(lhs);
unsigned rhs_base = hyperfloor(rhs);
if (lhs_base == rhs_base) {
// If lhs and rhs are equal, return lhs * 2
if (lhs == rhs) {
return (lhs << 1u) ^ __builtin_parity(lhs);
}
// Else return base*2 + (lhs - base) + (rhs - base)
return (lhs_base << 1u) ^ add_gray(lhs_base ^ lhs, lhs_base ^ rhs);
}
// It's easier to operate from the greatest value
if (lhs_base < rhs_base) {
swap(&lhs, &rhs);
swap(&lhs_base, &rhs_base);
}
// Compute lhs + rhs
if (lhs == lhs_base) {
return lhs ^ rhs;
}
// Compute (lhs - base) + rhs
unsigned tmp = add_gray(lhs ^ lhs_base, rhs);
if (hyperfloor(tmp) < lhs_base) {
// Compute base + (lhs - base) + rhs
return lhs_base ^ tmp;
}
// Here, hyperfloor(lhs) == hyperfloor(tmp)
// Compute hyperfloor(lhs) * 2 + ((lhs - hyperfloor(lhs)) + rhs) - hyperfloor(lhs)
return (lhs_base << 1u) ^ (lhs_base ^ tmp);
}
The algorithm uses the following utility functions in order tow work correctly:
// Swap two values
void swap(unsigned* a, unsigned* b)
{
unsigned temp = *a;
*a = *b;
*b = temp;
}
// Isolate the most significant bit
unsigned isomsb(unsigned x)
{
for (unsigned i = 1u ; i <= CHAR_BIT * sizeof(unsigned) / 2u ; i <<= 1u) {
x |= x >> i;
}
return x & ~(x >> 1u);
}
// Return the greatest power of 2 not higher than
// x where x and the power of 2 are encoded in Gray
// code
unsigned hyperfloor(unsigned x)
{
unsigned msb = isomsb(x);
return msb | (msb >> 1u);
}
So, how does it work?
I have to admit, it's quite a wall of code for something as « simple » as an addition. It is mostly based on observations about bit patterns in Gray codes; that is, I didn't prove anything formally, but I have yet to find cases where the algorithm doesn't work (if I don't take into account overflow, it does not handle overflow). Here are the main observations used to construct the algorithm, assume that everything is a Gray code:
2 * n = (n << 1) ⊕ parity(n)
If a is a power of 2 and a > b, then a ⊕ b = a + b
Consequently, i a is a power of 2 and a < b, then a ⊕ b = a - b. This will only work if b < 2 * a though.
If a and b have the same hyperfloor but are not equal, then a + b = (hyperfloor(a) << 1) ⊕ ((hyperfloor(a) ⊕ a) + (hyperfloor(b) ⊕ b)).
Basically, it means that we know how to multiply by 2, how to add a power of 2 to a smaller Gray code and how to subtract a power of 2 from a Gray code that is bigger than that power of 2 but smaller than the next power of 2. Everything else are tricks so that we can reason in terms of equal values or powers of 2.
If you want more details/information, you can also check this Q&A on Code Review which proposes a modern C++ implementation of the algorithm as well as some optimizations (as a bonus, there are some nice MathJax equations that we can't have here :D).
bool OrderUtils::shouldCptyAutoexecute(int Id)
{
bool res =
dummyCache::instance().getVal(Id).getWhitelabelType() == "ABCD";
if (!res)
res |= dummyCache::instance().getVal(Id).getIsPlc() == 1;
return res;
}
The above code checks for 2 Id's and returns true to res if any of the id is present in the database.
Can you suggest a way in which I can compare one more value from the databse table and return true to the value res..Also can you explain what does the second if statement do and the bitwise OR operator?
Sir, just let the short-circuit eval do this for you:
return dummyCache::instance().getVal(Id).getWhitelabelType() == "ABCD" ||
dummyCache::instance().getVal(Id).getIsPlc() == 1;
If the first is true, the second will not fire. Moreover, I assure you a remotely-reasonable optimizing compiler will not re-fire instance().getVal(id) if the returned object has not changed between the getWhitelabelType() and getisPlc() calls. In fact, i would all-but-guarantee it if getWhiteLabelType() is const. (and it certainly looks like it should be).
Regarding the bit work. The expression was pretty-much whacked. though it will work. Unless I read it wrong (and trust me, the list of people that will tell me I am will let me know quickly) it is performing a boolean eval, promoting the resulting true/false bool to an int, promoting the current value of res from bool to int (which is zero, so nothing special there), bitwise-OR-ing that with the expression int, then demoting the final int back to a bool to store in res . I'm surprised this doesn't flag at least a warning on the compiler.
It likely should have been if (!res) res ||= expr, and even then, it is pointless, as you can just use short circuit eval as in the top of this answer to cut out the local res entirely. Consider if res were false. Then the equivalent expression would be res = false || expr. But thats just res = expr. In the !res state it executes in, you may as well just use an assignment.
Finally, regarding adding a third field to your eval, it depends entirely on how you want it added. for an additional logical OR it is pretty simple.
For an expression like (A || B || C) you can just
return dummyCache::instance().getVal(Id).AField() == ATestValue ||
dummyCache::instance().getVal(Id).BField() == BTestValue ||
dummyCache::instance().getVal(Id).CField() == CTestValue;
For more complex operations, some judicious use of parenthesis will go a long way. For example, to return (A || B) && C:
return (dummyCache::instance().getVal(Id).AField() == ATestValue ||
dummyCache::instance().getVal(Id).BField() == BTestValue) &&
dummyCache::instance().getVal(Id).CField() == CTestValue;
Or perhaps (A && C) || (B && !C) (ok this is getting a little overboard...)
return (dummyCache::instance().getVal(Id).CField() == CTestValue)
? (dummyCache::instance().getVal(Id).AField() == ATestValue)
: (dummyCache::instance().getVal(Id).BField() == BTestValue);
Let a, b be positive integers with different values. Is there any way to simplify these expressions:
bool foo(unsigned a, unsigned b)
{
if (a % 2 == 0)
return (b % 2) ^ (a < b); // Should I write "!=" instead of "^" ?
else
return ! ( (b % 2) ^ (a < b) ); // Should I write "(b % 2) == (a < b)"?
}
I am interpreting the returned value as a boolean.
How is it different from
(a%2)^(b%2)^(a<b)
which in turn is
((a^b)&1)^(a<b)
or, indeed
((a ^ b) & 1) != (a < b)
Edited to add: Thinking about it some more, this is just the xor of the first and last bits of (a-b) (if you use 2's complement), so there is probably a machine-specific ASM sequence which is faster, involving a rotate instruction.
As a rule of thumb, don't mix operators of different operator families. You are mixing relational/boolean operators with bitwise operators, and regular arithmetic.
This is what I think you are trying to do, I'm not sure, since I don't understand the purpose of your code: it is neither readable nor self-explaining.
bool result;
bool a_is_even = (a % 2) == 0;
bool b_is_even = (b % 2) == 0;
if (a_is_even == b_is_even) // both even or both odd
result = a < b;
else
result = a >= b;
return result;
I program in C# but I'd think about something like this:
return (a % 2 == 0) && ((b % 2) ^ (a < b))
Considering from you comments that '^' is equivalent to '=='
If you are returning a truth value, a boolean, then your proposed changes do not change the semantics of the code. That's because bitwise XOR, when used in a truth context, is the same as !=.
In my view your proposed changes make the code much easier to understand. Quite why the author thought bitwise XOR would be appropriate eludes me. I guess some people think that sort of coding is clever. I don't.
If you want to know the relative performance of the two versions, write a program and time the difference. I'd be surprised if you could measure any difference between them. And I'd be equally surprised if these lines of code were your performance bottleneck.
Since there is not much information around this issue, try this:
int temp = (b % 2) ^ (a < b);
if (a % 2 == 0)
return temp;
else
return !temp;
This should be less code if the compiler hasn't optimized it already.