Simplify this expression - c++

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.

Related

Checking if a given group of integers contains a 0 value

Suppose I have a bunch of integers (10~20) and need to check if any of them equals 0. What's the most efficient way to do it? I don't want to evaluate a giant if(a=0 || b=0 || c=0 ||...) statement. I thought of if(abc... = 0) but if I remember correctly multiplication isn't a very quick process. Are there any other tricks, such as bit wise operations that would work? I'm trying to think as low level as possible to make this super efficient.
I'm pretty sure the fastest and clearest way to do this is with an explicit test:
int has_zero = !a || !b || !c || !d || !e ...;
Because the || and && are short-circuiting operators in C, evaluation stops as soon as the final result is known, so if (for instance) the b variable is zero, that satisfies the expression as true and stops evaluating the rest.
#AbhayAravinda suggested that !(a && b && c && d ...) might be more efficient, but I don't think so; because this is not so much doing an explicit not operation, but a low-level test-against-zero, this is a really easy test for pretty much any architecture to do reliably. I did a quick look at optimized assembler for both versions and there was no clear winner for performance, but I think the first version is clearer.
If every single cycle matters, then check both versions on your platform, but on my 64-bit Intel system, both gcc and clang do in fact generate the same assembly for both versions (with optimizations turned on).
Simple test code:
int a, b, c, d, e, f;
int test_or()
{
return !a || !b || !c || !d || !e || !f;
}
int test_and()
{
return ! (a && b && c && d && e && f);
}
int main()
{
return test_or() | test_and();
}
Compile this with gcc -S -O testfile.c and look at the resulting .s file.
Test each one in turn. Exploit the short-circuiting property of ||; place the variables in descending order of the probability of each being zero:
if (!a/*most likely to be zero*/ || !b || ...){
// one of them is zero
}
Most people give an answer like:
!a || !b || ...
(where a is the most probable one of being zero)
The idea is that, in case a is zero, then the rest of the sequence is not evaluated (because of not being necessary), which is a kind of optimisation, performed by the compiler.
This turns the question into: does your compiler perform this optimisation or not (and in case of "possibly yes", what are the parameters in order to enforce this)?
Can you tell us which compiler (version) you're working with? This might enable us verifying this.
You may look at the assembler output.
The !a || !b || !c || !d || !e || !f will give you a bunch of cmp and je statements. One pair for each variable. Because of boolean short cut evaluation, it may run very fast. Or not.
The maybe better and deterministic solution is using the bitwise AND operator. If one operand is 0, then the result will be 0. So someting like:
if (a & b & c & d & e & f & g & h & i & j & k)
will result in one mov and then and statements for each variable.
So, if the variable that is 0 is in the 2nd half of the if statement, then the bitweise AND will be faster.

C++ multiple operators: assign A or B not equal to C

I am currently learning from an SDL2/OpenGL2 example code, for ImGui. Then, I ran into a line (and a few more alike) as shown below. I believe this part binds SDL mouse events to IMGUI API. However, I do not quite understand how it works.
io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0
where,
ImGuiIO& io = ImGui::GetIO();
bool mouseDown[5]; // a member of ImGuiIO struct
static bool g_MousePressed[3] = { false, false, false };
Uint32 mouseMask = SDL_GetMouseState(&mx, &my);
(I hope above is enough information...)
What makes me the most confused is the the last part, not equal to 0. I could understand it, if it was a simple assignment of the result of an And and an Or operations. However, there is not equal to zero following at the end and I have not seen this before. I would like to get some help to understand this code please.
expression != 0
is a boolean expression and thus evaluates to either true or false which can be converted to integer values of 0 or 1.
#include <iostream>
int main() {
constexpr size_t SDL_BUTTON = 5;
for (size_t mouseMask = 0; mouseMask < 16; ++mouseMask) {
std::cout << mouseMask << ' '
<< (mouseMask & SDL_BUTTON) << ' '
<< ((mouseMask & SDL_BUTTON) != 0) << '\n';
}
}
Live demo: http://ideone.com/jcmosg
Since || is the logical or operator, we are performing a logical comparison that tests whether io.MouseDown != 0 or (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0 and yields a boolean value (true or false) promoted to whatever type io.mouseDown[0] is.
The code could actually have been written as:
io.MouseDown[0] = g_MousePressed[0] || (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT))
or
const bool wasPressed = g_mousePressed[0];
const bool newPress = mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT);
const either = (wasPressed == true) || (newPress == true);
io.MouseDown[0] = either;
or
if (g_mousePressed[0])
io.MouseDown[0] = 1;
else if (mouseMask & SDL_BUTTON(SDL_BUTTON_LEFT))
io.MouseDown[0] = 1;
else
io.MouseDown[0] = 0;
See http://ideone.com/TAadn2
If you are intending to learn, find yourself a good sandbox (an empty project file or an online ide like ideone.com etc) and teach yourself to experiment with pieces of code you don't immediately understand.
An expression a = b || c!=0 means a = (b!=0) || (c!=0). In boolean logic, b and b!=0 are equivalent. That's what I think the most confusing part. Once this is understood, there should be no problem.
Note that this expression should not be confused with a=b|c!=0, where | is a binary operation called "bit-wise or", as opposed to the logical operation ||, which is the logical "or". When doing b|c!=0, c!=0 is calculated first to yield a logical value 0 or 1, then b|0 or b|1 is calculated to do nothing (first case) or reset the last bit of the binary code of b to 1 (second case). Finally, that result is assigned to a. In this case, b and b!=0 are not equivalent, because the bit-wise or | is used instead of the logical or ||.
Similarly, & is the "bit-wise and" operator, while && is the logical "and". These two should not be confused either.
Notice that != has a higher precedence than ||, so the whole expression is indeed a simple assignment of the result of an OR.
The !=0 part is a way to turn the result of applying a bitmask into bool, as #AlekDepler said. Funny thing is its pretty much redundant (if mouseMask is of built-in integral type) as implicit conversion from say int to bool works exactly like !=0.

Understanding "Bitwise-And (&)" and "Unary complement(~)" in c++

I have some trouble understanding Bitwise-And and Unary Complement when both are used in this code snippet
if((oldByte==m_DLE) & (newByte==m_STX)) {
int data_index=0;
//This below line --- does it returns true if both the oldByte and newByte are not true
//and within timeout
while((timeout.read_s()<m_timeout) & ~((oldByte==m_DLE) & (newByte==m_ETX))) {
if(Serial.available()>0) {
oldByte=newByte;
newByte=Serial.read();
if(newByte==m_DLE) {
.
.
.
are the both operators & ~are performing a logical not operation like checking until if both oldByte and newByte are false
The above code is from the link --> line 227 of the code
I am trying to use the implement the code for my application in C but without the timing functions
if((oldByte==DLE) && (newByte== STX)) {
data_index = 0;
// is this the correct implematation for above C++ code to C
while(! ((oldByte== DLE) && (newByte== ETX))){
oldByte = newByte;
Is this method correct for implementing in C
(timeout.read_s()<m_timeout) & ~((oldByte==m_DLE) & (newByte==m_ETX))
is equivalent to (but probably less readable than)
(timeout.read_s()<m_timeout) && !(oldByte==m_DLE && newByte==m_ETX)
which is equivalent to (and IMO less readable than)
(timeout.read_s()<m_timeout) && (oldByte!=m_DLE || newByte!=m_ETX)
Edit: should add a caveat about short-circuiting. Although the particular example statements will all return the same value, using && or || will skip evaluating pieces that can't impact the result. This isn't important in your specific example, but could be very important in an example like this:
(oldByte!=nullptr & *oldByte == m_ETX) // will crash when oldByte=nullptr.
(oldByte!=nullptr && *oldByte == m_ETX) // will evaluate to false when oldByte=nullptr.
Since the equality-operator (==) yields 0 or 1 as a result, you can use bitwise and, too. (foo==1) & ~(bar==1) works too, since the AND with (foo==1), which always results in 1 and 0, masks all other bits in ~(bar==1). However, it is strongly recommended to use the logical counterparts &&, || and !.
The following would not work as expected:
if (~(bar == 1) & ~(foo == 1))
e.g. if foo = bar = 1, then it would evaluate to 0xfffffffe on ia32, which is different from 0 and therefore "TRUE"

Meaning of a comparator statement in C++

I am reading this code in C++
http://ajmarin.alwaysdata.net/codes/problems/952/ and I don't understand what this &= in the code does:
int k = 5;
int ts = 5;
bool possible = true;
And it have this line:
if(!(possible &= k == ts))
break;
I want to know what is the meaning of "&=" I am new in C++ language and I've never seen something like this for example in java, or at least I don't know the meaning.
The right hand of the statement returns "1" due to the fact that ( k == ts ) that is ( 5 == 5) but the left hand ( possible &= k ) don't know the meaning..
Thank you
It's equivalent to:
possible &= (k == ts);
if (! possible)
and is further equivalent to
possible = possible & (k == ts);
if (! possible)
Here, & is the bitwise AND. num & 0 will always gives you 0 while num & 1 will give you 1 if the least significant bit of num is 1 or 0 otherwise.
To read on, check out
Bitwise AND Assignment Operator (&=)
C++ Operator Precedence
It is a bitwise-AND-assignment, which is a Compound Assignment Operator. It is equivalent to the following statement:
possible = possible & (k == ts);
if(!possible)
....
Note that your original code-style is considered by many to be an anti-pattern, and you should in general avoid assignments in if statements (e.g. here and here).
&= is Bitwise AND assigning the result to the lhs( a&=b => a=a&b). (like +=)
It will perform a logical AND and assign the result to possible.
Due to Operator precedence the expression will be like: possible &= (k == ts).
Which means that it will evaulate (k == ts) resulting in a boolean, make a logical and with possible, store it in possible and return it as a result.

C++ bitwise OR operator

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);