Next: , Previous: , Up: Operators   [Index]


6.3.3 Unary Binary Logic

INTERCAL-72 C-INTERCAL CLC-INTERCAL J-INTERCAL
yes all versions all versions all versions

There are three unary operators in INTERCAL-72, each of which carries out a binary logic operation on adjacent bits of the number. The operators are and, or, and exclusive or; and and or are represented by an ampersand (&) and book (V) respectively, and exclusive or has the same notational problems as mingle, as it differs between Princeton and Atari syntax. It was represented by a bookworm, written V, backspace, -, in the Princeton INTERCAL-72 implementation, and this is still the most portable way to write it (C-INTERCAL and CLC-INTERCAL accept it). The Atari implementation of INTERCAL-72 wrote it with a what (?), and this is the representation originally used by C-INTERCAL (and still accepted), the only representation accepted by J-INTERCAL, the one most commonly used on Usenet, and the one used in this manual (although again, it’s worth pointing out that this isn’t portable). CLC-INTERCAL approximates a bookworm with the yen character, which being a currency character is one of the possible representations for mingle in C-INTERCAL; C-INTERCAL uses the rather confusing method of interpreting a yen character as exclusive-or if input in Latin-1 but as mingle if input in UTF-8. (This usually does the right thing, because CLC-INTERCAL doesn’t support UTF-8.) In the same way, CLC-INTERCAL has a C-INTERCAL compatibility option to allow the use of ? for exclusive-or.

The operators take each pair of consecutive bits in their arguments (that is, the least significant with the second least significant, the second least significant with the third least significant, the third least significant with the fourth least significant, and so on, with the pair consisting of the most significant and least significant being used to calculate the most significant bit of the result), and perform an appropriate logic operation on them; and sets a bit of the result if and only if both bits in the pair were set, or sets each bit corresponding to each pair where either bit was set, and exclusive or sets if and only if the bits in the pair had different values (that is, one was set, but not both). So for instance, #&26 is 16 (26 is 1A in hexadecimal or 11010 in binary); #V26 is 31 (11111 in binary), and #?26 is 23 (10111 in binary).

The most commonly seen use for these operators is to carry out bitwise ands, ors, and exclusive ors between two different 16-bit expressions, by mingling them together, applying a unary binary logic operator, and selecting every second bit of the result; such code often results due to people thinking in terms of some other language when writing INTERCAL, but is still often useful. (Historically, the first idiom added to the optimizer, apart from constant folding, was the mingle/unary/select sequence.) There are more imaginative uses; one impressive example is the exclusive or in the test for greater-than from the original INTERCAL-72 system library:

DO :5 <- "'?":1~'#65535$#0'"$":2~'#65535$#0'"'
     ~'#0$#65535'"$"'?":1~'#0$#65535'"$":2~'#0$
     #65535'"'~'#0$#65535'"
DO .5 <- '?"'&"':2~:5'~'"'?"'?":5~:5"~"#65535~
     #65535"'~'#65535$#0'"$#32768'~'#0$#65535'"
     $"'?":5~:5"~"#65535$#65535"'~'#0$#65535'"'
     "$"':5~:5'~#1"'~#1"$#2'~#3

The first statement works out the value of :1 bitwise exclusive or :2; the second statement then works out whether the most significant set bit in :5 (that is, the most significant bit that differs between :1 and :2) corresponds to a set bit in :2 or not. In case that’s a bit too confusing to read, here’s the corresponding optimizer idiom (in OIL):

((_1~:2)~((?32(:2~:2))^#2147483648))->(_1>(:2^_1))

(Here, the ^ refers to a bitwise exclusive or, an operation found in OIL but not in INTERCAL, which is why the INTERCAL version is so much longer.) The INTERCAL version also has some extra code to check for equality and to produce 1 or 2 as the output rather than 0 or 1.


Next: , Previous: , Up: Operators   [Index]