Operators

Order of Operations

When several BCX operators occur in the same statement, they are executed in the following order:


                                             Associativity
--------------------------------------------------------------------------------------------------------
     ()  parentheses or function call        left-to-right
     []  array element
      .   TYPE or UNION member
     ->   pointer reference to member
 SIZEOF  size of object in bytes
--------------------------------------------------------------------------------------------------------
     ++   post increment (lvalue++)          right-to-left
     ++   pre increment  (++lvalue)
     --   post decrement (lvalue--)
     --   pre decrement  (--lvalue)
      -   unary minus
      +   unary plus
      ~   bitwise complement ("ones complement") 
   BNOT   bitwise complement ("ones complement")          
      &   address of
      *   contents of
(data type)   cast (C-style type conversion)
--------------------------------------------------------------------------------------------------------
      *  multiply                            left-to-right
      /  divide
      %  remainder
--------------------------------------------------------------------------------------------------------
      +   add                                 left-to-right
      -   subtract
--------------------------------------------------------------------------------------------------------
     <<   bitwise left shift                  left-to-right
     >>   bitwise right shift
--------------------------------------------------------------------------------------------------------
     <    scalar less than                    left-to-right
     <=   scalar less than or equal to
     >    scalar greater than
     >=   scalar greater than or equal to
--------------------------------------------------------------------------------------------------------
      =     scalar equal                      left-to-right
EqualTo    scalar equal                        
      <>    scalar not equal
      ><    scalar not equal
NotEqualTo scalar not equal
--------------------------------------------------------------------------------------------------------
   BAND   bitwise and                         left-to-right
--------------------------------------------------------------------------------------------------------
      &   bitwise and                         left-to-right
--------------------------------------------------------------------------------------------------------
    XOR   bitwise exclusive or                left-to-right
--------------------------------------------------------------------------------------------------------
    BOR   bitwise or                          left-to-right
--------------------------------------------------------------------------------------------------------
      |   bitwise or                          left-to-right
--------------------------------------------------------------------------------------------------------
    AND   conditional and                     left-to-right
--------------------------------------------------------------------------------------------------------
ANDALSO   conditional and                     left-to-right
--------------------------------------------------------------------------------------------------------
     &&   conditional and                     left-to-right
--------------------------------------------------------------------------------------------------------
     OR   conditional or                      left-to-right
--------------------------------------------------------------------------------------------------------
 ORELSE   conditional or                      left-to-right
--------------------------------------------------------------------------------------------------------
     ||   conditional or                      left-to-right
--------------------------------------------------------------------------------------------------------
      =   assignment operator                 right-to-left
       also   +=    -=    *=    /=
              &=    |=   >>=   <<=
--------------------------------------------------------------------------------------------------------

      ,   sequential expression               left-to-right
--------------------------------------------------------------------------------------------------------

If the operations are different and are of the same level, the leftmost one is executed first and the rightmost last.

The order of operations in the following example


 DIM a%
 
 a% = 42 + 6 * 4 / 2 - 1
 
 PRINT a%

is as follows:


 1. 6 * 4   (= 24)
 2. 24 / 2  (= 12)
 3. 12 + 42 (= 54)
 4. 54 - 1  (= 53)

The above example can be expressed unambiguously, with parentheses, as


 DIM a%
 
 a% = (42 + ((6 * 4) / 2)) - 1
 
 PRINT a%

The assignment operators ^= and %= are not supported in BCX.

BCX uses the ^ symbol as the exponentiation operator, while the C language uses the ^ symbol for the bitwise exclusive or (XOR) operator.

The shortcut %= does not work in BCX because the % symbol is used as the integer identifier.

To use either, inline C code must be used, for example,


 ! a^=2;
 
 ! a%=2;

Exponentiation ^ operator

Example 1:


 DIM a, b

 b = -3
 a = 10 ^ b
 ? a

Result:


 0.001

Example 2:


 DIM a#
 
 a# = 5 ^ 2
 PRINT a#
 a# = 25 ^ 0.5
 PRINT a#

Result:


 25
 5

Example 3:


  DIM cum#[1000]
  DIM tcont, pd#
  
  tcont = 1
  cum#[tcont] = 17
  pd# = 2
  PRINT (cum#[tcont] ^ (1 / ((tcont + 1) / pd#)) - 1) * 100
 
  PRINT 7 ^ (MOD(13, 7))
  PRINT (SIN(13)) ^ (SIN(13))
  PRINT pd ^ (pd ^ 2)
 
  PRINT pd ^ pd
  PRINT 7 ^ (IMOD(3,2))
 
  PRINT POW(2, POW(2, POW(2, 2)))
  PRINT 2 ^ (2 ^ (2 ^ (2)))
  PRINT pd ^ pd - pd ^ (LOG(pd)) - (SIN(pd)) ^ 7
 

Result:


 1600
 117649
 0.6946632571379008
 16
 4
 7
 65536
 65536
 1.869218636052765

XOR operator


 Syntax:

 RetVal% = Number1 XOR Number2

 Parameters:

  • RetVal% Returned value.
  • Number1 Integer number.
  • Number2 Integer number.

Remarks:

The logical "exclusive or"(sometimes called the difference detector) operator compares corresponding bits in Number1 and Number2 then sets the corresponding bit in RetVal% according to the following table:


 ---------------------------------------------------------
  Bit in Expression1  Bit in Expression2  Bit in Result
 ---------------------------------------------------------
        1                  1                  0
        1                  0                  1
        0                  1                  1
        0                  0                  0
 ---------------------------------------------------------

Example 1:


 DIM a
 a = 1
 a = a XOR 1
 ? a
 a = a XOR 1
 ? a
 a = a XOR 1
 ? a

Result:


 0
 1
 0

Note the bit toggling effect.

Example 2:


 $COMMENT
 --------------------------------------------------------------------------------
 FUNctions with bits!  by Jeff Nope  jeffnope@hotmail.com
 Feel free to use these, you just can't hold me responsible,
 and give credit where credits due :-)
 --------------------------------------------------------------------------------
 All BitNum's are zero based
 --------------------------------------------------------------------------------
 a = BitClr(a,BitNum)  
 
 Clears a particular bit in variable a (to a value of 0).
 --------------------------------------------------------------------------------
 a = BitSet(a,BitNum)  
 
 Sets a particular bit in variable a (to a value of 1).
 --------------------------------------------------------------------------------
 b = BitTst(a,BitNum)  
 
 Determines whether a given bit is set in a.
 
 function result
 b = TRUE if the specified bit is set (that is, has a value of 1) and
 b = FALSE if the bit is cleared (that is, has a value of 0).
 --------------------------------------------------------------------------------
 a = BitTgl(a,BitNum)
 
 Toggles a particular bit in variable a
 --------------------------------------------------------------------------------
 z$ = dec2bin$(a,length)
 Converts variable a into a string representing the binary value of a. 
 The length variable is optional for formating, for example 8 gives a byte.
 This function is the opposite of BIN2DEC (z$) a BCX built in function.
 --------------------------------------------------------------------------------
 $COMMENT
 
 Dim a,b,i
 Dim z$
 z$="101001"
 
 ? "z$ = " & z$
 ? "a = BIN2DEC (z$)"
 a = BIN2DEC (z$)  'BCX built in function
 ? "a =" & a
 
 ?
 
 ?"z$ = dec2bin$(a,8) (with optional length):"
 z$ = dec2bin$(a,8) 'the optional length of 8, will cause leading zero's here
 ? "z$ = " & z$ & "b"
 
 ?
 
 ?"z$ = dec2bin$(a) (without the optional length):"
 z$ = dec2bin$(a)
 ? "z$ = " & z$ & "b"
 
 ?
 
 ? "a = BitSet(a,1)"
 a = BitSet(a,1)      'set bit 1 in variable a
 z$ = dec2bin$(a,8) 'the optional length of 8, will cause leading zero's here
 ? "a = " & a & " : " & z$ & "b"
 
 ?
 
 ? "a = BitClr(a,1)"
 a = BitClr(a,1)
 z$ = dec2bin$(a,8) 'the optional length of 8, will cause leading zero's here
 ? "a = " & a & " : " & z$ & "b"
 
 ?
 
 ? "a = BitTgl(a,1)"
 a=BitTgl(a,1)      'make sure it can toggle a bit
 z$ = dec2bin$(a,8) 'the optional length of 8, will cause leading zero's here
 ? "a = " & a & " : " & z$ & "b"
 
 ?
 
 ? "a = BitTgl(a,1)"
 a=BitTgl(a,1)      'make sure it can toggle a bit back
 z$ = dec2bin$(a,8) 'the optional length of 8, will cause leading zero's here
 ? "a = " & a & " : " & z$ & "b"
 
 ?
 
 
 ? "b = BitTst(a,i) loop:"
 for i = 7 to 0 step -1 'loop for 8 bits starting at the MSB
   b=BitTst(a,i)   ' Test the i'th bit in a
   ? b;            ' print the bits one at a time
 next
 
 getch()
 END
 
 Function BitTst(a,BitNum)  'BitNum is zero based
   Dim tmp
   tmp = a AND 1 << BitNum
   if tmp > 0 then tmp = 1
   Function = tmp
 End Function
 
 Function BitSet(a,BitNum)  'BitNum is zero based
   Dim tmp
   tmp = a OR 1 << BitNum
   Function = tmp
 End Function
 
 Function BitClr(a,BitNum)  'BitNum is zero based
   Dim tmp
   tmp = a AND ((1 << BitNum)XOR 0xFFFFFFFF)  'the XOR with all 1's causes all bits to toggle
   Function = tmp
 End Function
 
 Function BitTgl(a,BitNum)  'BitNum is zero based
   Dim tmp
   tmp = a XOR 1 << BitNum  'the XOR with 1 causes bit to toggle
   Function = tmp
 End Function
 
 Function dec2bin$ Optional (a,length=0)  'optionally formated
   dim i,tmp,t,T$
 
   if length=0 Then   'we don't know the length here
 
     tmp=a
     while tmp>0
       tmp = tmp >> 1
       length++
     wend
   end if
 
   t= 1
 
   for i= 1 to length 'we know the length here
     tmp= a AND t    'logical AND to test the bit
     if tmp = 0 then
       T$= "0" & T$
     else
       T$= "1" & T$
     end if
     t= t<<1
   next
 
   Function = T$
 End Function

BOR operator


 Syntax:

 RetVal% = Number1 BOR Number2

 Parameters:

  • RetVal% Returned value.
  • Number1 Integer number.
  • Number2 Integer number.

Remarks:

The bitwise BOR operator compares corresponding bits in numeric-expression1 and numeric-expression2, then sets the corresponding bit in the result according to the following table:


--------------------------------------------------------
  Bit in Expression1  Bit in Expression2  Bit in Result
--------------------------------------------------------
        1                  1                  1
        1                  0                  1
        0                  1                  1
        0                  0                  0
--------------------------------------------------------

Example:


 DIM a, b
 a = 0
 b = a BOR 1
 ? b
 b = a BOR 0
 ? b

Result:


 1
 0

BAND operator


 Syntax:

 RetVal% = Number1 BAND Number2

 Parameters:

  • RetVal% Returned value.
  • Number1 Integer number.
  • Number2 Integer number.

Remarks:

The BAND bitwise operator compares corresponding bits in two numeric expressions and sets the corresponding bit in the result to 1 if both bits are 1. The BAND operator uses this "truth table":


 --------------------------------------------------------
  Bit in Expression1  Bit in Expression2  Bit in Result
 --------------------------------------------------------
        1                  1                  1
        1                  0                  0
        0                  1                  0
        0                  0                  0
 --------------------------------------------------------

Example:


 DIM a, b
 a = 1
 b = a BAND 1
 ? b
 b = a BAND 0
 ? b

Result:


 1
 0

Example:

The following program demonstrates the use of BAND to determine whether a number is even or odd.


 DIM A%
 INPUT "Number ? "; A%

 IF A% BAND 1 THEN
   PRINT A%, " is odd"
 ELSE
   PRINT A%, " is even"
 END IF

BNOT operator


 Syntax:

 RetVal% = BNOT Number2

 Parameters:

  • RetVal% Returned value.
  • Number1 Integer number.

Remarks:

BNOT is a bitwise inversion operator which inverts bits in a numeric expression to 0 if 1 and to 1 if 0. The BNOT operator uses this "truth table":


 ------------------------------------------------------
  Bit in Expression  Bit in Result
 ------------------------------------------------------
      1                  0
      0                  1
 ------------------------------------------------------

 
 DIM a, b
 a = 12345
 b = BNOT a
 ? b
 b = BNOT b
 ? b

Result:


 -12346
  12345

ANDALSO and ORELSE Operators

ANDALSO and ORELSE were added to the BCX lexicon for the convenience of users of other BASIC dialects which have these operators. The functionality of ANDALSO is equivalent to the C language && operator which will evaluate the second operand only if the first evaluates as TRUE (non zero). The functionality of ORELSE is equivalent to the C language || operator which will evaluate the second operand only if the first evaluates as FALSE (zero).

Example:


 DIM AS BOOL bReault1, bReault2, bX1, bX2
 DIM szBuf$
 bX1 = TRUE
 bX2 = FALSE
 bReault1 = bX1 ANDALSO bX2
 bReault2 = bX1 ORELSE bX2
 PRINT "bX1 bX2 bX1 ANDALSO bX2 bX1 ORELSE bX2"
 sprintf(szBuf,"%3i %3i     %2i               %2i",bX1,bX2,bReault1, bReault2)
 PRINT szBuf
 bReault1 = bX1 AND bX2
 bReault2 = bX1 OR bX2
 PRINT "bX1 bX2 bX1 AND     bX2 bX1 OR     bX2"
 sprintf(szBuf,"%3i %3i     %2i               %2i",bX1,bX2,bReault1, bReault2)
 PRINT szBuf
 bReault1 = bX1 && bX2
 bReault2 = bX1 || bX2
 PRINT "bX1 bX2 bX1 &&      bX2 bX1 ||     bX2"
 sprintf(szBuf,"%3i %3i     %2i               %2i",bX1,bX2,bReault1, bReault2)
 PRINT szBuf
 PAUSE

Result:


 bX1 bX2 bX1 ANDALSO bX2 bX1 ORELSE bX2
   1   0      0                1
 bX1 bX2 bX1 AND     bX2 bX1 OR     bX2
   1   0      0                1
 bX1 bX2 bX1 &&      bX2 bX1 ||     bX2
   1   0      0                1

Truth Table for Logical Operators

Note well ! When using the operators NOT, AND, OR, XOR, a space must be before and after the operator, like this,


 IF (c > 64 AND c < 91) OR (c > 96 AND c < 123) THEN

Each operator returns results as indicated below. A "T" indicates a true value and an "F" indicates a false value. Operators are listed in order of operator precedence.


     Values of      Value Returned by Logical Operator
                           X    X    X
                     NOT  AND  OR   XOR
     X     Y          X    Y    Y    Y
     ------------------------------------
     T     T          F    T    T    F

     T     F          F    F    T    T

     F     T          T    F    T    T

     F     F          T    F    F    F

Bit Shift << and >> operators

Purpose: These operators shift the first parameter left (<<) or right (>>) by the number of places in the second parameter. Both parameters must be integers.

Shift Left << operator


 Syntax:

 RetVal% = IntNum% << NumPlaces%

 Parameters:

  • RetVal% Returned integer value.
  • IntNum% Integer number to be shifted left.
  • NumPlaces% Number of places to the left that IntNum% is to be shifted.

Remarks: Vacated right bits are set to 0.

Shift Right >> operator


 Syntax:

 RetVal% = IntNum% >> NumPlaces%

 Parameters:

  • RetVal% Returned integer value.
  • IntNum% Integer number to be shifted right.
  • NumPlaces% Number of places to the right that IntNum% is to be shifted.

Remarks: Vacated left bits are set to 0 if the integer type is unsigned. Otherwise, they are filled with copies of the sign bit.

Example:


 DIM value%

 value% = 32768 << 1 'Shift left 1 place
 PRINT value% ' value% will equal 65536
 
 value% = 32768 >> 1 'Shift right 1 place
 PRINT value% ' value% will equal 16384

Relational Operators

Relational operators are used to compare two values. The result of the comparison is either "true"(nonzero) or "false"(zero). This result can then be used to make a decision regarding program flow. Although BCX treats any nonzero value as true, true is usually represented by 1. When arithmetic and relational operators are combined in one expression, the arithmetic operations are always done first.


  Operator   Relation                 Expression

      =      Equality                    X = Y
      <>     Inequality                  X <> Y
      <      Less than                   X < Y
      >      Greater than                X > Y
      <=     Less than or equal to       X <= Y
      >=     Greater than or equal to    X >= Y

Note: The keyword IS can be used in place
      of the = equality relational operator.

      IS     Equality                    X IS Y

      The LET keyword can precede statements
      containing the equality relational operator(=).

    LET A% = 6 * 6

In the following example BCX will give a different answer than most dialects of BASIC.


 DIM RetVal%, A%, B%, C%
 
 RetVal% = 3 * ((A% >= B%) + (B% <= C%))
 
 ? RetVal%

Using BCX, the example above returns an integer value of 6. Using QBASIC, the result is -6. The reason is because most BASIC dialects define TRUE as -1, but in the C language, TRUE is defined as 1. Each parenthetical evaluates to TRUE and in QBASIC, the statement reduces down to 3 * ( -1 + -1). In BCX, the statement reduces down to 3 * (1 + 1).

Example:


 DIM c
 DIM d
  
 c = 42
 d = 6
 
 IF d < c  THEN ? "It works!"
 IF d > c  THEN ? "error"
 IF d <> c THEN ? "It works!"
 IF d = c  THEN ? "error"
 IF d <= c THEN ? "It works!"
 IF d >= c THEN ? "error"
 

Result:


 It works!
 It works!
 It works!

String Concatenation Operators + and &

A string expression consists of string constants, string variables, and other string expressions combined by string concatenation operators. The act of combining two strings is called concatenation.

String concatenation will not work with strings containing an embedded ASCII NULL.

In BCX, string concatenation may use the plus (+) symbol for concatenation as long as one of the string expressions being concatenated is a string variable appended with the $ string data type specifier. Otherwise, string concatenation must be performed using the ampersand (&) symbol.

For example, the following program fragment combines the string variables A$ and B$ to produce the value FILENAME:


 DIM A$
 DIM B$

 A$ = "FILE"
 B$ = "NAME"
 PRINT A$ + B$
 PRINT "NEW " & A$ & B$

Result:

 FILENAME
 NEW FILENAME

The following code is not legal!


 DIM A AS STRING
 DIM B AS STRING
  
 A = "FILE"
 B = "NAME"
 PRINT A + B ' Either A and/or B must be A$ and/or B$
 PRINT "NEW " + A + B ' Either A and/or B must be A$ and/or B$ 
 

Result:The compiler will complain that operands of + have incompatible types.

String Comparison Operators

Like the String Concatenation Operators in the section above, String Comparison Operators must be used with a string data type specifier ($). This code, which does a string comparison between between "T" and "S",


 DIM S AS STRING 
 DIM T AS STRING
 S="Test"
 T="Test"
 IF T$ = S$ THEN 
   PRINT " S equals T"
 ELSE
   PRINT " S does not equal T"
 END IF

works as expected while the following code, in which the string data type specifiers ($) have not been appended,


 DIM S AS STRING 
 DIM T AS STRING
 S="Test"
 T="Test"
 IF T = S THEN 
   PRINT " S equals T"
 ELSE
   PRINT " S does not equal T"
 END IF

will not produce the expected answer for a string comparison because in the line


 IF T = S THEN 

which BCX translates as


if(T==S)

the "T" and the "S" are translated as pointers.

With the string data type specifiers appended, that is, "T$" and "S$", the BCX translator produces a string comparison


if(strcmp(T,S)==0)

In BCX string notation is handled opposite compared to most other BASIC dialects. In BCX strings are nothing more than a CHAR PTR which means you can do assignments and comparisons to the pointer itself or to the contents that it is being pointing to. In BCX we indicate we want to work with the contents by using the "$" type specifier. No type specifier means we want to work with the pointer itself and not the space that it points to

Strings can be compared using the following relational operators:


  Operator   Relation                 Expression

      =      Equality                    X$ = Y$
      <>     Inequality                  X$ <> Y$
      <      Less than                   X$ < Y$
      >      Greater than                X$ > Y$

NOTE: <= and >= cannot be used to compare strings.
      The keyword IS can be used in place
      of the = equality relational operator.

String comparisons are made by taking corresponding characters from each string and comparing their ASCII codes. If the ASCII codes are the same or all the characters in both strings, the strings are equal. If the ASCII codes differ, the lower code number precedes the higher. If the end of one string is reached during string comparison, the shorter string is smaller if they are equal up to that point. Leading and trailing blanks are significant.

Example:


  DIM c$
  DIM d$
 
  c$ = "test_"
  d$ = "test"
 
  IF d$ < c$  THEN ? "It works!"
  IF d$ > c$  THEN ? "error"
  IF d$ <> c$ THEN ? "It works!"
  IF d$ = c$  THEN ? "error"
 

Result:


 It works!
 It works!

Increment and Decrement Operators

Post Increment ++ operator

Purpose: Appending ++ to a variable will increase the value of the variable by 1.


 Syntax:

 variable++

 Parameters:

  • None

Remark: If a postincremented variable appears in an expression, the expression is evaluated using the current value of variable and then the variable is incremented by 1.

++ Pre Increment operator

Purpose: Prepending ++ to a variable will increase the value of the variable by 1.


 Syntax:

 ++variable

 Parameters:

  • None

Remark: If a preincremented variable appears in an expression, the variable is incremented by 1 and then the expression is evaluated.

Post Decrement -- operator

Purpose: Appending -- to a variable will decrease the value of the variable by 1.


 Syntax:

 variable--

 Parameters:

  • None

Remark: If a postdecremented variable appears in an expression, the expression is evaluated using the current value of variable and then the variable is decremented by 1.

-- Pre Decrement operator

Purpose: Prepending -- to a variable will decrease the value of the variable by 1.


 Syntax:

 --variable

 Parameters:

  • None

Remark: If a predecremented variable appears in an expression, the variable is decremented by 1 and then the expression is evaluated.

Example:


 DIM a
   
 a = 42
 ? a++   'post increment(print a, 42, then a = a + 1)
 ? a     'print a, 43 
 
 ? ++a   'pre increment(a = a + 1, then print a, 44)
 ? a     'print a, 44 
 
 ? a--   'post decrement(print a, 44, then a = a - 1)
 ? a     'print a, 43 
 
 ? --a   'pre decrement (a = a - 1, then print a, 42)
 ? a     'print a, 42
 

Result:


 42
 43
 44
 44
 44
 43
 42
 42

Assignment Operators

Plus equals += operator

Purpose: A shorthand form of variable = variable + numeric-expression.


 Syntax:

 variable += numeric-expression

 Parameters:

  • None

Minus equals -= operator

Purpose: A shorthand form of variable = variable - numeric-expression.


 Syntax:

 variable -= numeric-expression

 Parameters:

  • None

Multiplied by equals *= operator

Purpose: A shorthand form of variable = variable * numeric-expression.


 Syntax:

 variable *= numeric-expression

 Parameters:

  • None

Divided by equals /= operator

Purpose: A shorthand form of variable = variable / numeric-expression.


 Syntax:

 variable /= numeric-expression

 Parameters:

  • None

Example:


 DIM a
 a = 42
 
 a += 2    'same as a = a + 2
 ? a
 
 a -= 2    'same as a = a - 2
 ? a
 
 a *= 2    'same as a = a * 2
 ? a
 
 a /= 2    'same as a = a / 2
 ? a

Result:


 44
 42
 84
 42