# Binary Operators

Binary operators require two arguments. Click on any operator in the list below for details and examples.

(See also: Unary Operators and Operator Precedence.)

## Notes about the 16-bit workspace

Many of the operator descriptions will say something like "computes (some function) of a 16-bit number." This does not mean that the operator does not work on smaller byte or nibble values, but rather that the computation is done in a 16-bit workspace. If the value is smaller than 16 bits, the BASIC Stamp pads it with leading 0s to make a 16-bit value. If the 16-bit result of a calculation is to be packed into a smaller variable, the higher-order bits are discarded (truncated).

+ (Addition)

The Addition operator (+) adds variables and/or constants, returning a 16-bit result. It works exactly as you would expect with unsigned integers from 0 to 65535. If the result of addition is larger than 65535, the carry bit will be lost. If the values added are signed 16-bit numbers and the destination is a 16-bit variable, the result of the addition will be correct in both sign and value.

    SYMBOL  value1  = W0
    SYMBOL  value2  = W1

    Main:
      value1 = -99
      value2 = 100
      value1 = value1 + value2                      ' Add the numbers
      DEBUG value1                                  ' Show the result (1)
      END

    value1  VAR     Word
    value2  VAR     Word

    Main:
      value1 = -1575
      value2 = 976
      value1 = value1 + value2                      ' Add the numbers
      DEBUG SDEC ? value1                           ' Show the result (-599)
      END

- (Subtraction)

The Subtraction operator (-) subtracts variables and/or constants, returning a 16-bit result. It works exactly as you would expect with unsigned integers from 0 to 65535. If the result is negative, it will be correctly expressed as a signed 16-bit number.

    SYMBOL  value1  = W0
    SYMBOL  value2  = W1

    Main:
      value1 = 199
      value2 = 100
      value1 = value1 - value2                      ' Subtract value2 from value1
      DEBUG value1                                  ' Show the result (99)
      END

    value1  VAR     Word
    value2  VAR     Word

    Main:
      value1 = 1000
      value2 = 1999
      value1 = value1 - value2                      ' Subtract value2 from value1
      DEBUG SDEC ? value1                           ' Show the result (-999)
      END

* (Multiplication)

The Multiply operator (*) multiplies variables and/or constants, returning the low 16 bits of the result. It works exactly as you would expect with unsigned integers from 0 to 65535. If the result of multiplication is larger than 65535, the excess bits will be lost. Multiplication of signed variables will be correct in both number and sign, provided that the result is in the range -32767 to +32767.

    SYMBOL  value1  = W0
    SYMBOL  value2  = W1

    Main:
      value1 = 1000
      value2 = 19
      value1 = value1 * value2                      ' Multiply the numbers
      DEBUG value1                                  ' Show the result (19000)
      END

    value1  VAR     Word
    value2  VAR     Word

    Main:
      value1 = 1000
      value2 = 19
      value1 = value1 * value2                      ' Multiply the numbers
      DEBUG SDEC ? value1                           ' Show the result (19000)
      END

** Multiply High (Return Upper 16 Bits)

The Multiply High operator (**) multiplies variables and/or constants, returning the high 16 bits of the result. When you multiply two 16-bit values, the result can be as large as 32 bits. Since the largest variable supported by PBASIC is 16 bits, the highest 16 bits of a 32-bit multiplication result are normally lost. The ** (double-star) operator gives you these upper 16 bits. For example, suppose you multiply 65000 ($FDE8) by itself. The result is 4,225,000,000 or $FBD46240. The * (star, or normal multiplication) operator would return the lower 16 bits, $6240. The ** operator returns $FBD4.

    SYMBOL  value1  = W0
    SYMBOL  value2  = W1

    Main:
      value1 = $FDE8
      value2 = value1 ** value1                     ' Multiply value1 by itself
      DEBUG $value2                                 ' Show upper 16 bits
      END

    value1  VAR     Word
    value2  VAR     Word

    Main:
      value1 = $FDE8
      value1 = value1 ** value1                     ' Multiply value1 by itself
      DEBUG HEX ? value1                            ' Show upper 16 bits
      END

An interesting application of the ** operator is to multiply by a known fractional value less than one. The fraction value is expressed in units of 1/65536. To find the fractional ** parameter, multiply the fraction part by 65536. Example:

    SYMBOL  Frac    = 47554                         ' = 0.72562 x 65536
    SYMBOL  value   = W0

    Test:
      value = 10000
      value = value ** Frac                         ' Multiply 10000 by 0.72562
      DEBUG value                                   ' Show result (7256)

    Frac    CON     47554                           ' = 0.72562 x 65536
    value   VAR     Word

    Test:
      value = 10000
      value = value ** Frac                         ' Multiply 10000 by 0.72562
      DEBUG ? value                                 ' Show result (7256)

*/ Multiply Middle (Return Middle 16 Bits)

The Multiply Middle operator (*/) multiplies variables and/or constants, returning the middle 16 bits of the 32-bit result. This has the effect of multiplying a value by a whole number and a fraction. The whole number is the upper byte of the multiplier (0 to 255 whole units) and the fraction is the lower byte of the multiplier (0 to 255 units of 1/256 each). The */ (star-slash) operator gives you an excellent workaround for the BASIC Stamp's integer-only math. Suppose you want to multiply a value by 1.5. The whole number, and therefore the upper byte of the multiplier, would be 1, and the lower byte (fractional part) would be 128, since 128/256 = 0.5. It may be clearer to express the */ multiplier in hex—as $0180—since hex keeps the contents of the upper and lower bytes separate.

    value1  VAR     Word

    Main:
      value1 = 100
      value1= value1 */ $0180                       ' Multiply by 1.5 [1 + (128/256)]
      DEBUG ? value1                                ' Show result (150)
      END

To calculate constants for use with the */ operator, take the desired (mixed) target multiplier and multiply it by 256, then convert the result to a whole integer: INT(mixed * 256). For instance, if our target multiplier is Pi (3.14159), the resulting constant to represent that value for the */ operator is INT(3.13159 * 256) = INT(804.25) = 804 ($0324). Notice that the upper byte is $03 (decimal 3; the whole number), and the lower byte is $24 (decimal 36; the fractional part that means 36/256). So the constant Pi for use with */ would be $0324. This isn’t a perfect match for Pi, but the error is only about 0.1%.

/ (Division)

The Division operator (/) divides variables and/or constants, returning a 16-bit result. It works exactly as you would expect with unsigned integers from 0 to 65535. Use / only with positive values; signed values do not provide correct results. Here’s an example of unsigned division:

    SYMBOL  value1  = W0
    SYMBOL  value2  = W1

    Main:
      value1 = 1000
      value2 = 5
      value1 = value1 / value2                      ' Divide the numbers
      DEBUG value1                                  ' Show the result (200)
      END

    value1  VAR     Word
    Value2  VAR     Word

    Main:
      value1 = 1000
      value2 = 5
      value1 = value1 / value2                      ' Divide the numbers
      DEBUG DEC ? value1                            ' Show the result (200)
      END

A workaround to the inability to divide signed numbers is to have your program divide absolute values, then negate the result if one (and only one) of the operands was negative. All values must lie within the range of -32767 to +32767.

    sign    VAR     Bit                             ' bit to hold the sign
    value1  VAR     Word
    Value2  VAR     Word

    Main:
      value1 = 100
      value2 = -3200
      sign = value1.Bit15 ^ value2.Bit15            ' determine result sign
      value2 = ABS value2 / ABS value1              ' divide absolute values
      IF (sign = 1) THEN value2 = -value2           ' correct sign if negative
      DEBUG SDEC ? value2                           ' show the result (-32)
      END

// (Modulus—Remainder of Division)

The Modulus operator (//) returns the remainder left after dividing one value by another. Some division problems don’t have a whole-number result; they return a whole number and a fraction. For example, 1000 / 6 = 166.667. Integer math doesn’t allow the fractional portion of the result, so 1000 / 6 = 166. However, 166 is an approximate answer, because 166 * 6 = 996. The division operation left a remainder of 4. The // (double-slash) operator returns the remainder of a given division operation. Naturally, numbers that divide evenly, such as 1000 / 5, produce a remainder of 0.

    SYMBOL  value1  = W0
    SYMBOL  value2  = W1

    Main:
      value1 = 1000
      value2 = 6
      value1 = value1 // value2                     ' get remainder of value1 / value2
      DEBUG value1                                  ' show the result (4)
      END

    value1  VAR     Word
    value2  VAR     Word

    Main:
      value1 = 1000
      value2 = 6
      value1 = value1 // value2                     ' get remainder of value1 / value2
      DEBUG DEC ? value1                            ' show the result (4)
      END

MIN (Limit a Value to Specified Low)

The Minimum operator (MIN) limits a value to a specified 16-bit positive minimum. The syntax of MIN is:

Value MIN Limit

Where Value is a constant or variable value to perform the MIN function upon and Limit is the minimum Value that value is allowed to be. When used in a statement like result = Value MIN Limit, its logic is, 'if Value is less than Limit, then make result = Limit; if Value is greater than or equal to Limit, make result = Value.' MIN works in positive math only; its comparisons are not valid when used on two’s complement negative numbers, since the positive-integer representation of a number like -1 ($FFFF in hexadecimal or 65535 in unsigned decimal) is larger than that of a number like 10 ($000A hexadecimal or 10 decimal). Use MIN only with unsigned integers. Because of the way fixed-size integers work, you should be careful when using an expression involving MIN 0. For example, result = 0 - 1 MIN 0 will result in 65535 because 0 - 1 = -1 (65535 in two's compliment math) and 65535 is greater the minimum boundary 0.

    SYMBOL  value1  = W0
    SYMBOL  value2  = W1

    Main:
      FOR value1 = 100 TO 0 STEP -10                ' walk value1 from 100 to 0
        value2 = value1 MIN 50                      ' use MIN to clamp at 50
        DEBUG value2                                ' show "clamped" value
      NEXT
      END

    value1  VAR     Word
    value2  VAR     Word

    Main:
      FOR value1 = 100 TO 0 STEP 10                 ' walk value1 from 100 to 0
        value2 = value1 MIN 50                      ' use MIN to clamp at 50
        DEBUG DEC ? value2 MIN 50                   ' show "clamped" value
      NEXT
      END

MAX (Limit a Value to a Specified High)

The Maximum operator (MAX) limits a value to a specified 16-bit positive maximum. The syntax of MAX is:

Value MAX Limit

...where Value is a constant or variable value to perform the MAX function upon and Limit is the maximum value that Value is allowed to be. When used in a statement like result = Value MAX Limit, its logic is, ‘if Value is greater than Limit, then make result = Limit; if Value is less than or equal to Limit, make result = Value.’ MAX works in positive math only; its comparisons are not valid when used on two’s complement negative numbers, since the positive-integer representation of a number like -1 ($FFFF in hexadecimal or 65535 in unsigned decimal) is larger than that of a number like 10 ($000A hexadecimal or 10 decimal). Use MAX only with unsigned integers. Because of the way fixed-size integers work, you should be careful when using an expression involving MAX 65535. For example, result = 65535+1 MAX 65535 will result in 0 because 65535 + 1 = 0 (in 16-bits) and 0 is less than the maximum boundary 65535.

    SYMBOL  value1  = W0
    SYMBOL  value2  = W1

    Main:
      FOR value1 = 0 TO 100 STEP 10                 ' Walk value1 from 0 to 100
        value2 = value1  MAX  50                    ' Use MAX to clamp at 50
        DEBUG  value2                               ' Show "clamped" value
      NEXT
      END

    value   VAR     Word

    Main:
      FOR value = 0 TO 100 STEP 10                  ' Walk value from 0 to 100
        DEBUG ? value MAX 50                        ' Show "clamped" value
      NEXT
      END

DIG (Returns Specified Digit of Number)

The Digit operator (DIG) returns the specified decimal digit of a 16-bit positive value. Digits are numbered from 0 (the right-most digit) to 4 (the left-most digit of a 16-bit number; 0 to 65535).

    value   VAR     Word
    idx     VAR     Nib

    Main:
      value = 9742
      DEBUG ? value DIG 2                           ' Show digit 2 (7)

      FOR idx = 0 TO 4
        DEBUG ? value DIG idx                       ' Show digits 0 - 4 of 9742
      NEXT
      END

REV (Reverses specified number of bits)

The Reverse operator (REV) returns a reversed (mirrored) copy of a specified number of bits of a value, starting with the rightmost bit (LSB). For instance, %10101101 REV 4 would return %1011, a mirror image of the least significant four bits of the value.

      DEBUG BIN4 ? %11001010 REV 4                  ' Mirror lower 4 bits (%0101)

<< (Shifts Bits Left by Specified Amount)

The Shift Left operator (<<) shifts the bits of a value to the left a specified number of places. Bits shifted off the left end of a number are lost; bits shifted into the right end of the number are 0s. Shifting the bits of a value left n number of times has the same effect as multiplying that number by 2 to the nth power. For instance 100 << 3 (shift the bits of the decimal number 100 left three places) is equivalent to 100 * 23.

    value   VAR     Word
    idx     VAR     Byte

    Main:
      value = %1111111111111111

      FOR idx = 1 TO 16                             ' loop 16 times
        DEBUG BIN16 ? Value << idx                  ' display shifted value
      NEXT
      END

>> (Shift Bits Right by Specified Amount)

The Shift Right operator (>>) shifts the bits of a variable to the right a specified number of places. Bits shifted off the right end of a number are lost; bits shifted into the left end of the number are 0s. Shifting the bits of a value right n number of times has the same effect as dividing that number (unsigned) by 2 to the nth power. For instance 100 >> 3 (shift the bits of the decimal number 100 right three places) is equivalent to 100 / 23.

    value   VAR     Word
    idx     VAR     Byte

    Main:
      value = %1111111111111111

      FOR idx = 1 TO 16                             ' loop 16 times
        DEBUG BIN16 ? Value >> idx                  ' display shifted value
      NEXT
      END

& (Bitwise AND)

The Bitwise AND (&) operator returns the bit pattern of the logical AND of each bit pair in two binary values. Each bit of these values is subject to the following logic:

        0 & 0 = 0
        0 & 1 = 0
        1 & 0 = 0
        1 & 1 = 1

The result returned by & will contain 1s in only those bit positions in which both input values contain 1s.

    SYMBOL  value1  = B0
    SYMBOL  value2  = B1
    SYMBOL  result  = B2

    Main:
      value1 = %00001111
      value2 = %10101101
      result = value1 & value2
      DEBUG %result                                 ' Show AND result (%00001101)
      END

      DEBUG BIN8 ? %00001111 & %10101101            ' Show AND result (%00001101)

| (Bitwise OR)

The Bitwise OR (|) operator returns the bit pattern of the logical OR of each bit pair in two binary values. Each bit of the values is subject to the following logic:

        0 | 0 = 0
        0 | 1 = 1
        1 | 0 = 1
        1 | 1 = 1

The result returned by | will contain 1s in any bit positions in which one or the other (or both) input values contain 1s.

    SYMBOL  value1  = B0
    SYMBOL  value2  = B1
    SYMBOL  result  = B2

    Main:
      value1 = %00001111
      value2 = %10101001
      result = value1 | value2
      DEBUG  %result                                ' Show OR result (%10101111)
      END

      DEBUG BIN8 ? %00001111 | %10101001            ' Show OR result (%10101111)

^ (Bitwise XOR)

The Bitwise Exclusive OR operator (|) returns the bit pattern of the logical XOR of each bit pair in two binary values. Each bit of the values is subject to the following logic:

        0 ^ 0 = 0
        0 ^ 1 = 1
        1 ^ 0 = 1
        1 ^ 1 = 0

The result returned by ^ will contain 1s in any bit positions in which one or the other (but not both) input values contain 1s.

    SYMBOL  value1  = B0
    SYMBOL  value2  = B1
    SYMBOL  result  = B2

    Main:
      value1 = %00001111
      value2 = %10101001
      result = value1 ^ value2
      DEBUG  %result                                ' Show OR result (%10100110)
      END

      DEBUG BIN8 ? %00001111 ^ %10101001            ' Show OR result (%10100110)

&/ (Bitwise AND NOT)

The Bitwise AND NOT operator (&/) returns the bit pattern of the logical AND NOT of each bit pair in two binary values. Each bit of the values is subject to the following logic:

        0 &/ 0 = 0
        0 &/ 1 = 0
        1 &/ 0 = 1
        1 &/ 1 = 0

The result returned by &/ will contain 1s in any bit positions in which the first value is 1 and the second value is 0.

    SYMBOL  value1  = B0
    SYMBOL  value2  = B1
    SYMBOL  result  = B2

    Main:
      value1 = %00001111
      value2 = %10101001
      result = value1 &/ value2
      DEBUG  %result                                ' Show AND NOT result (%00000110)
      END

|/ (Bitwise OR NOT)

The OR NOT operator (|/) returns the bitwise OR NOT of two values. Each bit of the values is subject to the following logic:

        0 |/ 0 = 1
        0 |/ 1 = 0
        1 |/ 0 = 1
        1 |/ 1 = 1

The result returned by |/ will contain 1s in any bit positions in which the first value is 1 or the second value is 0.

    SYMBOL  value1  = B0
    SYMBOL  value2  = B1
    SYMBOL  result  = B2

    Main:
      value1 = %00001111
      value2 = %10101001
      result = value1 |/ value2
      DEBUG  %result                                ' Show OR NOT result (%01011111)
      END

^/ (Bitwise XOR NOT)

The Bitwise XOR NOT operator (^/) returns the bit pattern of the logical XOR NOT of each bit pair in two binary values. Each bit of the values is subject to the following logic:

        0 ^/ 0 = 1
        0 ^/ 1 = 0
        1 ^/ 0 = 0
        1 ^/ 1 = 1

The result returned by ^/ will contain 1s in any bit positions in which the first value and second values are equal.

    SYMBOL  value1  = B0
    SYMBOL  value2  = B1
    SYMBOL  result  = B2

    Main:
      value1 = %00001111
      value2 = %10101001
      result = value1 ^/ value2
      DEBUG  %result                                ' Show OR NOT result (%01011001)
      END

AND (Logical AND)

The AND operator returns the logical AND of two values or expressions. Note that in the BASIC Stamp, a non-zero value is considered True (T), zero is considered False (F). The values/expressions are subject to the following logic:

        F AND F = F
        F AND T = F
        T AND F = F
        T AND T = T

The result returned by AND will be True or False.

    score   VAR     Byte
    avg     VAR     Byte

    Main:
      score = 93
      avg = 89

      IF (score > 80) AND (avg > 70) THEN
        DEBUG "Promote to next grade."              ' both conditions are True
      ELSE
        DEBUG "Consider additional tutoring."       ' at least one condition is False
      ENDIF
      END

OR (Logical OR)

The OR operator returns the logical OR of two values or expressions. Note that in the BASIC Stamp, a non-zero value is considered True (T), zero is considered False (F). The values/expressions are subject to the following logic:

        F OR F = F
        F OR T = T
        T OR F = T
        T OR T = T

The result returned by OR will be True or False.

    score   VAR     Byte
    avg     VAR     Byte

    Main:
      score = 63
      avg = 89

      IF (score < 80) OR (avg < 70) THEN
        DEBUG "Consider additional tutoring."       ' at least one condition is True
      ELSE
        DEBUG "Promote to next grade."              ' both conditions are False
      ENDIF
      END

XOR (Logical XOR)

The XOR operator returns the logical Exclusive OR of two values or expressions. Note that in the BASIC Stamp, a non-zero value is considered True (T), zero is considered False (F). The values/expressions are subject to the following logic:

        F XOR F = F
        F XOR T = T
        T XOR F = T
        T XOR T = F

The XOR operator can be confusing at first. An easy way to remember the logic is: If one or the other is True -- but not both -- then the result is True, otherwise the result is False.

The result returned by XOR will be True or False.

    turnL   VAR     Bit
    turnR   VAR     Bit

    Main:
      turnL = 0
      turnR = 1

      IF (turnL = 1) XOR (turnR = 1) THEN           ' one or other is True
        DEBUG "Turning - ", "L" + ("R" - "L" * turnR)
      ELSE
        DEBUG "Continue straight."                  ' both True or both False
      ENDIF
      END

ATN (Returns Arctangent of Vector (X, Y))

The Arctangent operator (ATN) returns the angle to the vector specified by X and Y coordinate values. In the BASIC Stamp, the angle is returned in binary radians (0 to 255) instead of degrees (0 to 359). Coordinate input values are limited from -127 to 127 (signed bytes) as shown in the diagram below:

    idx     VAR     Nib                             ' loop counter
    xCoord  VAR     Byte                            ' x coordinate of vector
    yCoord  VAR     Byte                            ' y coordinate of vector
    brads   VAR     Word                            ' angle in brads
    degr    VAR     Word                            ' angle in degrees

    Main:
      FOR idx = 0 TO 7                              ' load vector data

        LOOKUP idx, [ 1, 1, 0, -1, -1, -1,  0,  1], xCoord
        LOOKUP idx, [ 0, 1, 1,  1,  0, -1, -1, -1], yCoord

        brads = xCoord ATN yCoord                   ' get angle of vector
        degr = brads * 180 / 128                    ' convert to degrees

        DEBUG DEC (idx + 1), ": ",
              "ATN (", SDEC xCoord, ", ", SDEC yCoord, ")",
              CRSRX, 18, "= ", DEC brads, "  (", DEC degr, ")", CR
      NEXT
      END

HYP (Returns Hypotenuse)

The Hypotenuse operator (HYP) returns the length of the hypotenuse of a right triangle with sides of length A and B. Side length (vector) input values are limited to -127 to 127 (signed bytes).

      DEBUG ? 3 HYP 4                               ' display hypotenuse of 5

Go to Welcome page

BASIC Stamp Help Version 2.5.4

Copyright © Parallax Inc.

8/8/2012