Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weird conditional format [closed]

Throughout my endless journey around the vast and dangerous planes of this beautiful thing also known as The Internet I came across a mysterious, old, white-bearded wizard whose name shall not be mentioned. Despite being very powerful death quickly took him away.

Moments before he took his last breath he passed me a scroll and while fainting away whispered

Take this and spread the knowledge

Quickly after his death his body transformed into energy, pure energy which spread around the universe.

The scroll contained this bit of code:

#include <iostream>
int main()
{
    int x = 3;
    while(2 <= x <= 5)
        std::cout << x++;
}

The mystery remains to this day:

How is the condition evaluated?

like image 414
user1233963 Avatar asked Apr 27 '26 06:04

user1233963


2 Answers

Always to true, because 2<=x either evaluates to 1 or 0, both of which are <=5.

So that's effectively an infinite loop:

while( (2 <= x) <= 5)
    std::cout<<x++;
like image 175
Luchian Grigore Avatar answered Apr 28 '26 19:04

Luchian Grigore


Well, the composer of this scroll wanted to express a condition we call chained operator notation, well known from mathematics (maybe the wizard was a mathematician?):

Let x ∈ ℜ, 2 ≤ x ≤ 5. Then ...

Normally, this isn't possible in C++, C, Java and a lot of other languages with similar expression evaluation logic. There are libraries which enable such a feature, but on the other hand introduce verbosity because you have to wrap one of the arguments first. Also, it isn't very readable for a programmer.

If you write the expression in such languages as the wizard did on this scroll, it will be evaluated from left to right:

while ( (2 <= x) <= 5 )
    ...

which is always true, since 2 <= x is either true or false and implicitly cast to an integer value of 1 or 0, respectively, which is always less or equal 5.

To express the condition as the mathematician wanted it to be, you have to use the syntax

while ( (2 <= x) && (x <= 5) )
    ...

or use a utility function to express exactly this:

template<class T>
bool between(const T& arg, const T& min, const T& max) {
    return !(arg < min) && !(max < arg);
}


while ( between(x, 2, 5) )
    ...

Note how I wrote the condition in between: It only requires an implementation of operator<(T, T), easing the implementation of custom types.

like image 35
leemes Avatar answered Apr 28 '26 20:04

leemes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!