0

I am still learning the fundamentals of programming through C++ and was trying some applications on C++ operators, but it seems there are things about them that I still don't understand.

I tried writing the following line to test the possibility of using equal to (==) as a ternary operator:

cout << "(2+2 == 2*2 == pow(2, 2)) == " << (2+2 == 2*2 == pow(2, 2)) << endl;

The output was 0

So, I suspected that this might be because the return value of pow(2,2) is a double while that of the first two operands is an integer and thus I tried the following:

cout << "(2+2 == 2*2 == int(pow(2, 2))) == " << (2+2 == 2*2 == int(pow(2, 2))) << endl;
cout << "(double(2+2) == double(2*2) == pow(2, 2)) == " << (double(2+2) == double(2*2) == pow(2,2)) << "\n\n";

The output for both lines of code was also 0.

I have also tried the use of parentheses to reduce the number of operands but ended up with the same output.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • 1
    `x == y == z` is evaluated from left to right. In your case `2+2 == 2*2` is `true`, and `true` (represented as `1`) is not equal to `pow(2,2)`. – wohlstad Jul 19 '23 at 10:24
  • I was looking for duplicate, but you already got answers in the meantime. Nevertheless, here's also worthy reading about `pow` with integers: [Why does pow(n,2) return 24 when n=5, with my compiler and OS?](https://stackoverflow.com/questions/25678481/why-does-pown-2-return-24-when-n-5-with-my-compiler-and-os) – Yksisarvinen Jul 19 '23 at 10:29
  • Above is C but same concept and misunderstanding. – Yunnosch Jul 19 '23 at 10:33
  • btw not only the return value of `pow` is `double`, also the paramters types. `pow` is not for integers. – 463035818_is_not_an_ai Jul 19 '23 at 10:50
  • C++ is just too complicated. Trying random things, "to test the possibility" of them working in some suspected way, will rarely succeed. The only way to learn C++, effectively, is to follow an organized study course [from a good C++ textbook](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Sam Varshavchik Jul 19 '23 at 11:08

3 Answers3

5

a == b == c does not do what you expect it to do! It first calculates a == b, which is either true or false – or as integral value 1 or 0 – and then compares this value against c – so you can ever only get a final value of true if c compares equal to either 0 or 1, which it ever cannot in given case. To achieve the equivalence to mathematical a = b = c you need to compare one value twice against the other two, e.g. a == b && a == c

Which one of the values you chose to compare twice doesn't matter for the final result – but you shouldn't calculate the same value twice (at least if it's a complex calculation); if all three values are calculated store the one to compare twice in a temporary variable; in concrete case:

int tmp = 2 + 2;
// (admitted, SUCH A SIMPLE ONE would not be worth the
//  effort, compiler would optimize it anyway)

std::cout << (tmp == 2*2 && tmp == pow(2,2));

Be aware, though: pow introduces floating point – while it would still produce correct results if inputs are integers you might run into rounding issues for other values (see e.g. here or search here on SO for comparing floating point values), so (apart from being overkill here anyway) you always should think twice if you really want to use it (and yes, there are valid use cases…)!

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
  • Thx fellow programmer :) – SeriousN00b Jul 19 '23 at 10:42
  • I understand what you are trying to say regarding the pow() function, but what is the point of using the type "unsigned" for the temporary variable? – SeriousN00b Jul 20 '23 at 10:04
  • @SeriousN00b Here actually none, you could have used signed int just as well, doesn't matter. Only positive values involved vs. signed literals, one could easily argue for both. I encourage usage of unsigned values in those scenarios where negative values are meaningless (like dimensions of objects, have you ever seen a ball with -10 cm diameter???) to express exactly this fact (length of arrays, for instance, cannot be negative either). – Aconcagua Jul 20 '23 at 12:47
  • @SeriousN00b Switched to `int`, might appear more natural in given case as not using unsigned literals (`2u`) either. I personally have a slight tendency towards unsigned types as these have no undefined behaviour issues e.g. on overflowing or bit operations – in those cases where it really doesn't matter… – Aconcagua Jul 20 '23 at 13:07
3

Because comparison with == have left-to-right associativity, the expression

2+2 == 2*2 == pow(2, 2)

is really equal to

(2+2 == 2*2) == pow(2, 2)

That means you will be comparing the result of 2+2 == 2*2, with the result of pow(2, 2).

Because 2+2 is equal to 2*2 the result of the first comparison will be true. This is then implicitly converted to the value 1 which is then compared to the result of the pow(2,2) call.

And 1 == pow(2,2) is false. Which is then displayed as its numeric value equivalent of 0.


And some nitpicking: A three-way comparison isn't really a three-way comparison, as shown above it's really two separate comparisons. So this is not a "ternary operator".

C++ really only have one ternary operator, and that's the conditional operator ?:.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

C++ doesn’t work in the way you think. You can put multiple comparisons together but they will have an order of doing things.

Let’s take this as an example: (2+2 == 2*2 == pow(2, 2)). It will mean “let’s compare 2+2 and 2*2, the result is ‘true’ (1). Then let’s compare ‘true’ to pow(2,2), that’s not equal, so let’s return ‘false’ (0)”

So this means you can’t compare multiple values to each other just putting them together. It’s the same as “2*3+2”, it isn’t the same as “2*3” and “3+2” somehow, it’s a single thing.

So in short: you can only compare two things by value. If you need more you need to separate them to multiple groups of two and then join them with “and”. So this works: (2+2 == 2*2 && 2*2 == pow(2, 2))

Sami Kuhmonen
  • 30,146
  • 9
  • 61
  • 74
  • Thank you so much, never expected such a quick reply, and please forgive my ignorance, I am kind of new to programming as a whole and to C++ lol – SeriousN00b Jul 19 '23 at 10:40