Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitwise operations in APL?

We need to make a program that emulates the division of IEEE floating point numbers for my computer architecture class. I pretty much have this done, but I thought it would be interesting to see what the program would look like in APL, yet as far as I can tell there is no (straightforward) way to do bitwise operations in APL (bitwise and/or, shifting, etc...). What is the simplest way to do this in APL, if possible?

like image 580
Nathan BeDell Avatar asked Apr 18 '15 15:04

Nathan BeDell


1 Answers

The clean (= the way you want to use) way of doing this in APL is:

  1. convert number(s) to a bit vector (or bit matrix or higher dimension APL value),
  2. do the shift rotate etc. operation on the bit vector, and
  3. convert back to the numbers

Steps 1 and 3 are fairly simple: APL has two conversion operators encode (⊤) and decode(⊥) that do it. Bit vectors are only a special case; the operators work with arbitrary bases (including hex).

Examples:

      ⍝ convert 13 to 4-bit vector. The number of 2s is the result length
      2 2 2 2 ⊥ 13
1 1 0 1

      2 ⊥ 1 1 0 1   ⍝ convert back
13

An APL programmer would not write 2 2 2 2 to indicate the desired length of the result vector, but instead (4⍴2). This is because for longer arguments of ⊤ (like 64 in your case) the code is far more readable.

Negative integers are a bit more tricky because there are different formats like 1-complement or 2-complement. ⊤ and ⊥ work but you have to take some care.

There are a few cool things that ⊤ and ⊥ provide. First of all you can convert several numbers in one go:

      2 2 2 2 ⊤ 1 2 3
0 0 0
0 0 0
0 1 1
1 0 1

Next, as already said, they work for other bases like 16 for hexadecimal results:

      16 16 16 16 ⊤ 50000
12 3 5 0

The result is numeric, so you may want to convert it to characters:

      '0123456789ABCDEF'[⎕IO+16 16 16 16⊤50000]
C350

The most tricky case is floating point (and thus also complex) numbers.

Most APL interpreters have system functions for that, for example ⎕DR in APL68000 or 27 ⎕CR in GNU APL. ⎕DR returns a binary vector directly while 27 ⎕CR in GNU APL converts a 64-bit-IEEE floating point number to a 64-bit 2s-complement integer that can then be converted as described above.

Once you have converted your number(s) to bit vector(s), the rest is simple:

  1. Indexing ([]) for accessing individual bits
  2. Take (↑) and drop (↓) for shifting bits
  3. Rotate (⊖ or ⌽) for rotating bits
  4. The boolean functions And/Or/Nand/Nor/Not (∧ ∨ ⍲ ⍱ and ∼) for binary operations.
like image 98
Jürgen Sauermann Avatar answered Sep 28 '22 18:09

Jürgen Sauermann