Binary operators require two arguments. Click on any operator in the list below for details and examples.
(See also: Unary Operators and Operator Precedence.)
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).
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
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
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
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)
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%.
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
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
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
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
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
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)
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
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
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)
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)
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)
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
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
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
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
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
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
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
BASIC Stamp Help Version 2.5.4
Copyright © Parallax Inc.
8/8/2012