Jump to content

Chained size comparison in an ACS if() statement


Recommended Posts

Doing a player height check - discovered that a chained comparison doesn't work as I expected:

 

This does not work as expected (chained comparisons like this are valid for e.g. javascript):

if(  (heightcheckmap[checkheightmapid] - 32) <= (GetActorZ(0)/65536) <= (heightcheckmap[checkheightmapid] + 32) ){
            print(s:"unblock");
            checkHeight = 1;
}

But this does...

if( (GetActorZ(0)/65536) <= heightcheckmap[checkheightmapid] + 32 && (GetActorZ(0)/65536) >= heightcheckmap[checkheightmapid] - 32){
            print(s:"unblock");
            checkHeight = 1;
}

It's a minor thing, but frustrated me as my logic didn't work as expected until I explicitly tested both conditions as separate entries...

 

Share this post


Link to post

It's because the result of a comparison is a boolean value (true, false, 1, 0), and each one is evaluted on their own from left to right. So

 

-32 <= 0 <= 32

 

will turn to

 

1 <= 32

 

since -32 <= 0 is true (1). It does work in this case, but for example in this it wont:

 

-64 <= -32 <= 0

 

since -64 <= -32 is true (1), but 1 <= 0 is false.

 

It's the same in JS, btw (and many, many, many other languages).

 

 

Share this post


Link to post

Not quite.

 

The ACS code did not evaluate the n1 < x < n2 as I expected, but JS does. Just tried and in JS, these:

 

                //jstest
                let x = 2;
                if(1<x<3){
                    console.log("fish1");
                }
                
                if(x > 1 && x < 3){
                    console.log("fish2");
                }

both evaluate to true, whereas for these ACS blocks (which AFAICS are functionally identical):

int heightcheckmap[3] = {0,-1012,-840};
if(  (heightcheckmap[checkheightmapid] - 32) <= (GetActorZ(0)/65536) <= (heightcheckmap[checkheightmapid] + 32) ){
    log(s:"fish 3");    //not logged
}

if(  (GetActorZ(0)/65536) <= heightcheckmap[checkheightmapid] + 32   &&  (GetActorZ(0)/65536) >= heightcheckmap[checkheightmapid] - 32 ){
    log(s:"fish 4");    //logged OK
}

only the second evaluates to true.

 

This syntax is certainly valid in Python, which may be where my usage comes from (I use Python in my IRL job):

 

https://www.kite.com/python/answers/how-to-check-if-a-number-is-between-two-numbers-in-python

https://stackoverflow.com/questions/13628791/determine-whether-integer-is-between-two-other-integers

 

[BTW, I check the range for the player z-height in case the player is on a step...]

 

>>> EDIT <<<

Oh, I see my mistake. Javascript does indeed evaluate one pair to true, THEN uses that return value (an implicit 0 or 1) as one half of the test for the second pair. Sometimes it will behave as per the python syntax, sometimes not. 

Edited by smeghammer

Share this post


Link to post
27 minutes ago, smeghammer said:

Not quite.

 

The ACS code did not evaluate the n1 < x < n2 as I expected, but JS does. Just tried and in JS, these:

 


                //jstest
                let x = 2;
                if(1<x<3){
                    console.log("fish1");
                }
                
                if(x > 1 && x < 3){
                    console.log("fish2");
                }

both evaluate to true, whereas for these ACS blocks (which AFAICS are functionally identical): 

 

It just works because of the numbers you chose. That example also works in ACS, but it doesn't do what you apparently think it does. That's event what the accepted answer on SO says.

 

Try what this evaluates to in JS:

 

-1044 <= -1012 <= -980

 

(hint: it'll evaluate to false)

 

It doesn't work with those numbers because -1044 <= -1012 evaluates to true (1), and 1 <= -980 evaluates to false (0).

Edited by boris

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...