Logic trouble

General FreeBASIC programming questions.
Post Reply
badidea
Posts: 2594
Joined: May 24, 2007 22:10
Location: The Netherlands

Logic trouble

Post by badidea »

A poll/quiz: Without running the code, how many will "IS_SOLID" be printed if you run it?

Code: Select all

const IS_SOLID = &B0001
const IS_CLIMB = &B0010

dim as long flag = IS_SOLID

if flag and IS_SOLID then print "IS_SOLID"
if not (flag and IS_SOLID) then print "IS_SOLID"
if flag and IS_CLIMB = IS_CLIMB then print "IS_SOLID"
Last edited by badidea on Dec 21, 2019 9:59, edited 1 time in total.
Iczer
Posts: 99
Joined: Jul 04, 2017 18:09

Re: Logic trouble

Post by Iczer »

first and third - 2 times?
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Logic trouble

Post by D.J.Peters »

badidea wrote this
if flag and IS_CLIMB = IS_CLIMB then print "IS_SOLID"
=
if (flag<>0) and (IS_CLIMB = IS_CLIMB) then print "IS_SOLID"

but is was meant !
if (flag and IS_CLIMB) = IS_CLIMB then print "IS_SOLID"

Joshy
badidea
Posts: 2594
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Logic trouble

Post by badidea »

D.J.Peters wrote:...
So, your answer is also 2 ?
fxm
Moderator
Posts: 12159
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Logic trouble

Post by fxm »

Parsed as:

Code: Select all

if ( flag and IS_SOLID )                  [ <> 0 ]   then print "IS_SOLID"
if ( not (flag and IS_SOLID) )            [ <> 0 ]   then print "IS_SOLID"
if ( flag and ( IS_CLIMB = IS_CLIMB ) )   [ <> 0 ]   then print "IS_SOLID"
paul doe
Moderator
Posts: 1740
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Logic trouble

Post by paul doe »

Indeed, the answer is 3. The second one is easy enough if one realizes all operations involved are binary and not logic (the expression evaluates to a non-zero value in 2's complement arithmetic), but the real gotcha lies in the third one:

Code: Select all

if flag and IS_CLIMB = IS_CLIMB then print "IS_SOLID 3"
Since both the 'and' and the '=' operators have the same associativity but '=' has higher precedence, it gets evaluated first and the result is again a non-zero value.

Truculent because, when coding in FreeBasic, you get used to see the '=' symbol in assignments, thus you kind of naturally expect the above expression to yield 'false'. That's why other languages usually discriminate between assignment and comparison operators:

Code: Select all

#include <iostream>

const int 
  IS_SOLID = 0x1,
  IS_CLIMB = 0x2;

int 
  flag = IS_SOLID;

int main()
{
  if( flag & IS_SOLID )
    std::cout << "IS_SOLID 1" << std::endl;
  if( ~( flag & IS_SOLID ) )
    std::cout << "IS_SOLID 2" << std::endl;
  if( flag & IS_CLIMB == IS_CLIMB )
    std::cout << "IS_SOLID 3" << std::endl;
  
  return( 0 );
}
That's why I'm a big fan of RPN ;)
fxm
Moderator
Posts: 12159
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Logic trouble

Post by fxm »

if a = b
can be replaced with:
if not (a <> b)

So:
if flag and not IS_CLIMB <> IS_CLIMB then print "IS_SOLID"
or:
if flag and not (IS_CLIMB <> IS_CLIMB) then print "IS_SOLID"
badidea
Posts: 2594
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: Logic trouble

Post by badidea »

I had both (2) and (3) in one subroutine. The routine did not work as intended :-)
Post Reply