#include <iostream>
int main()
{
int a = 18, b = 44, total = 0, total2 = 0;
total += (a % 2 == 0) ? b : 0; //44
total2 += a % 2 ? b : 0; //0
a >>= 1;
b <<= 1;
printf("%d\n%d", total, total2);
}
modulo and boolean logic for a bit operation is clunky ... a&1 is true for odd, a^1 is true for even gets rid of the excess == and provides a consistent look and feel. This should work on signed values, though not all bit stuff will.
modulo and boolean logic for a bit operation is clunky ... a&1 is true for odd
Checking if a number is even or odd isn't really a "bit operation" though. It's a mathematical property. What you do when you do a % 2 == 0 is that you're checking if the number is divisible by 2 which is what it means for a number to be even. Checking the least significant bit accomplishes the same thing but might be less obvious (and therefore make the code less "readable") to some people, especially the fact that it also works for negative numbers (assuming two's complement which is what's used in practice and what's being mandated by the standard since C++20).
a^1 is true for even
That doesn't seem to work very well.
1 2 3 4 5 6 7 8 9
#include <iostream>
int main()
{
for (int a = 0; a <= 5; ++a)
{
std::cout << a << " is " << (a ^ 1 ? "even" : "odd") << "\n";
}
}
0 is even
1 is odd
2 is even
3 is even
4 is even
5 is even
The correct test for even using xor is (a ^ 1) == a + 1. But this is no simpler than just using a % 2 == 0 (or just !(a % 2)). Consider:
1 2 3 4 5 6
int main() {
for (int a = 0; a <= 5; ++a) {
std::cout << "xor " << a << " is " << ((a ^ 1) == a + 1 ? "even" : "odd") << "\n";
std::cout << "mod " << a << " is " << (!(a % 2) ? "even" : "odd") << "\n";
}
}
1 2 3 4 5 6 7 8 9 10 11 12
xor 0 is even
mod 0 is even
xor 1 is odd
mod 1 is odd
xor 2 is even
mod 2 is even
xor 3 is odd
mod 3 is odd
xor 4 is even
mod 4 is even
xor 5 is odd
mod 5 is odd
you are right. And I don't see a 1 op way to test even, everything needs at least 2 operations. There should be one ... I feel like I missed something dumb, that you can't say 'is this bit 0' in one touch...
The simplest for even I can come up with is to bit inverse and then test bit 1:
~a & 1
or to just invert the result for odd test:
!(a & 1)
that you can't say 'is this bit 0' in one touch
Can this even be done in assembler? I don't recall such but I haven't used assembler for many years. As far as I remember you'd test bit 0 is set and then true (odd) or false (even) would be done with the following branch test.
I think some chips have a way to test a single bit but in general, I don't know of anything you can do in asm here that you can't do with logic ops for a typical processor.
I agree that test odd and branch to even is the most efficient way. Which is what I have done for so long that I had forgotten about the even test weirdness.