Are these ternary operators the same?


Hello,

What are the differences between these?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  #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);

}
The condition (left side of the ?) is different.

(a % 2 == 0) is true when a is an even number.

a % 2 is 1 (which is treated as true) when a is an odd number.
Regarding the ternary operator itself, the only operator with lower precedence is the comma operator, so the parentheses usually aren’t necessary, but can be used for clarity.
https://en.cppreference.com/w/cpp/language/operator_precedence

My opinion is to prefer direct boolean expressions over implicit int conversions.
Last edited on
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.
Last edited on
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
Last edited on
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...
Registered users can post here. Sign in or register to post.