2015-04-18 3 views
4

Нам нужно создать программу, которая эмулирует разделение чисел с плавающей запятой IEEE для моего класса архитектуры компьютера. Я в значительной степени сделал это, но я подумал, что было бы интересно посмотреть, как будет выглядеть программа в APL, но насколько я могу судить, нет (простого) способа выполнения побитовых операций в APL (побитовое и/или , смещение и т. д.). Каков самый простой способ сделать это в APL, если это возможно?Побитовые операции в APL?

ответ

8

Чистый (= так, как вы хотите использовать) способ сделать это в APL является:

  1. номер новообращенный (ей) битового вектора (или битовой матрицы или выше размер значения APL),
  2. сделать сдвиг вращать и т.д. операции на битовом векторе, и
  3. преобразовать обратно к номерам

Этапы 1 и 3 достаточно просты: АПЗ имеет два оператора преобразования кодирования (⊤) и декодирование (), Которые делают это. Бит-векторы - это только частный случай; операторы работают с произвольными базами (включая шестнадцатеричные).

Примеры:

 ⍝ 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 

АПЗ программист не написать 2 2 2 2, чтобы указать требуемую длину результирующего вектора, но вместо этого (4⍴2). Это связано с тем, что для более длинных аргументов ⊤ (например, 64 в вашем случае) код гораздо читабельнее.

Отрицательные целые числа несколько сложнее, потому что существуют разные форматы, такие как 1-дополнение или 2-дополнение. ⊤ и ⊥, но вам нужно проявлять осторожность.

Есть несколько интересных вещей, которые ⊤ и ⊥ обеспечивают. Прежде всего, вы можете конвертировать несколько номеров в одном дыхании:

 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 

В результате числовой, так вы можете преобразовать его в символы:

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

самым сложным случаем является плавающей точкой (и, таким образом, также комплекс) номера.

Большинство интерпретаторов APL имеют системные функции для этого, например DRDR в APL68000 или 27 ⎕CR в GNU APL. ⎕DR возвращает двоичный вектор напрямую, а 27 ⎕CR в GNU APL преобразует число с плавающей запятой 64 бит-IEEE в 64-разрядное целое число с добавлением 2s, которое затем может быть преобразовано, как описано выше.

После того, как вы превратили свой номер (ы) для битового вектора (ов), а остальные просто:

  1. Indexing ([]) для получения доступа к отдельным битам
  2. Take (↑) и падение (↓) для смещающих битов
  3. Поворот (⊖ или ⌽) для вращающихся бит
  4. Булевы функции и/или/Nand/Nor/Not (∧ ∨ ⍲ ⍲ и ~) для двоичных операций.
1

В зависимости от системы APL, вот нечистым способ сделать это. Некоторые APL-системы имеют функцию [] DR-системы, которая позволяет быстро и свободно преобразовывать содержимое переменных из одного типа данных в другой. Если у вас есть 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 делает трудной частью преобразования числа с плавающей запятой в вектор битов, а затем обратно. (Это может быть именно то, что вам нужно изучить в классе компьютерной архитектуры, но это не плохой способ проверить ваш ответ)

Внимание: С помощью этой методики вы можете построить значения, которые недействительны числа с плавающей запятой. Это может негативно повлиять на сбой интерпретатора, систему или оставить что-то, что может вызвать проблему позже. Обязательно выполните )CLEAR после эксперимента.

Смежные вопросы