APL 中的按位运算?

Bitwise operations in APL?

我们需要制作一个程序来模拟我的计算机体系结构的 IEEE 浮点数除法 class。我几乎已经完成了这项工作,但我认为看看程序在 APL 中的样子会很有趣,但据我所知,没有(直接的)方法可以在 APL 中进行按位运算(按位 and/or、移位等...)。如果可能的话,在 APL 中执行此操作的最简单方法是什么?

在 APL 中执行此操作的干净(=您想要使用的方式)方法是:

  1. 将数字转换为位向量(或位矩阵或更高维度 APL 值),
  2. 对位向量进行移位旋转等操作,
  3. 转换回数字

第 1 步和第 3 步相当简单:APL 有两个转换运算符编码 (⊤) 和解码 (⊥) 来执行此操作。位向量只是一个特例;经营者 使用任意基数(包括十六进制)。

示例:

      ⍝ 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

APL 程序员不会 编写 2 2 2 2 来指示结果向量的所需长度,而是 (4⍴2)。这是因为对于较长的 ⊤ 参数(如您的情况下的 64),代码可读性更高。

负整数有点棘手,因为有不同的格式,例如 1-complement 或 2-complement。 ⊤ 和 ⊥ 工作,但你必须小心。

⊤ 和 ⊥ 提供了一些很酷的东西。首先你可以转换 一口气数个号码:

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

接下来,如前所述,它们适用于其他基数,例如十六进制结果的 16:

      16 16 16 16 ⊤ 50000
12 3 5 0

结果为数字,因此您可能需要将其转换为字符:

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

最棘手的情况是浮点数(因此也是复数)。

大多数 APL 解释器都有相应的系统函数,例如 APL68000 中的 ⎕DR 或 GNU APL 中的 27 ⎕CR。 ⎕DR returns 直接是二进制向量,而 GNU APL 中的 27 ⎕CR 将 64 位 IEEE 浮点数转换为 64 位 2s 补码整数,然后可以如上所述进行转换。

一旦您将数字转换为位向量,剩下的就很简单了:

  1. 用于访问单个位的索引 ([])
  2. 取(↑)落(↓)移位位
  3. 旋转(⊖或⌽)旋转位
  4. 二元运算的布尔函数And/Or/Nand/Nor/Not(∧∨⍲⍱和∼)。

根据您的 APL 系统,这里有一种不干净的方法。一些 APL 系统有一个 []DR 系统函数,它允许快速和松散的方式将变量的 content 从一种数据类型转换为另一种数据类型。如果你有 Dyalog APL(可能这将在 APL2000 中工作),试试这个:

      )CLEAR
      []IO := 0  // sorry, no APL chars
      []PP := 16
      a := 11 []DR 7.42  // 11 means "type number 1, boolean, 1 bit"
      a
1 0 1 0 1 1 1 0 0 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 1 1 1 1 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 1 1 1 0 0 0 0 1 1 1 0 1 0 1 0 0 0 0 0 0
      a[42]
1
      a[42] := 0
      645 []DR a   // 645 means "type number 5, double, 64 bit"
7.388750000000003
      )CLEAR

这里 []DR 完成了将浮点数转换为位向量然后再转换回来的困难部分。 (这可能正是你在计算机体系结构中需要学习的东西class,但它是检查答案的好方法)

警告:使用此技术,您可以构造不是有效浮点数的值。这可能会导致解释器、系统崩溃或留下一些可能在以后导致问题的东西。一定要)CLEAR试验后