EMAWP

Z MERA 400 wiki
Skocz do: nawigacja, szukaj

EMAWP to biblioteka i narzędzia pozwalające operować na liczbach długich i zmiennoprzecinkowych w taki sam sposób, w jaki robi to Arytmometr Wielokrotnej Precyzji. Biblioteka używana jest przez emulator EM400 do realizowania funkcjonalności AWP, oraz przez assembler EMAS i deassembler EMDAS do konwersji liczb zmiennoprzecinkowych między konwencją zapisu MERY-400 a formatem systemu, na którym narzędzia działają.

Repozytorium źródeł EMAWP: https://github.com/jakubfi/emawp

Z biblioteką dostarczane jest narzędzie emawp pozwalające wykonywać operacje AWP na liczbach zmiennoprzecinkowych w linii poleceń. Jego wywołanie ma jedną z postaci:

emawp [-v] <argumrnt>
emawp [-v] -n <argument>
emawp [-v] -a|-s|-m|-d <argument> <argument>
emawp -h

gdzie:

  • argument - liczba zmiennoprzecinkowa (np. 1.4512) lub trzy 16-bit liczby hexadecymalne (np. 0x4234 0xe3fa 0x0001)
  • -n - normalizacji argumentu
  • -a - wykonanie operacji dodawania argumentów
  • -s - wykonanie operacji odejmowania argumentów
  • -m - wykonanie operacji mnożenia argumentów
  • -d - wykonanie operacji dzielenia argumentów
  • -v - włączenie trybu gadatliwego
  • -h - wyświetlenie pomocy.

Przykłady użycia

Normalizacja

Liczba zmiennoprzecinkowa zapisana w postaci używanej przez AWP jako 0x2f00 0x0000 0x0002 ma wartość 1.46875, ale jest zdenormalizowana. Znormalizować ją można następująco:

> emawp -n 0x2f00 0x0000 0x0002
 in1:  DENORM  ----  0x2f00 0x0000 0x0002  ->  1.468750000000000000000000000000000000000000
norm:      OK  ----  0x5e00 0x0000 0x0001  ->  1.468750000000000000000000000000000000000000

Operacje arytmetyczne

Wykonanie dodawania liczby 0.5 i 1.5 w postaci używanej przez AWP ma postać:

> emawp -a 0x4000 0x0000 0x0000 0x6000 0x0000 0x0001
 in1:      OK  ----  0x4000 0x0000 0x0000  ->  0.500000000000000000000000000000000000000000
 in2:      OK  ----  0x6000 0x0000 0x0001  ->  1.500000000000000000000000000000000000000000
 add:      OK  ----  0x4000 0x0000 0x0002  ->  2.000000000000000000000000000000000000000000

I jest ono równoznaczne wykonaniu tej samej operacji z użyciem zapisu z kropką:

> emawp -a 0.5 1.5
 in1:      OK  ----  0x4000 0x0000 0x0000  <-  0.500000000000000000000000000000000000000000
 in2:      OK  ----  0x6000 0x0000 0x0001  <-  1.500000000000000000000000000000000000000000
 add:      OK  ----  0x4000 0x0000 0x0002  ->  2.000000000000000000000000000000000000000000

Typy argumentów można również mieszać.

Flagi i błędy

Zgodnie z zachowaniem AWP, emawp prezentuje flagi i błędy operacji. Druga kolumna wyjścia opisuje stan operacji:

  • OK - poprawny
  • UDFLOW - podmiar dzielenia zmiennoprzecinkowego
  • OVFLOW - nadmiar dzielenia zmiennoprzecinkowego
  • DENORM - argument zdenormalizowany

Kolumna trzecia zawiera flagi, które ustawiła operacja arytmetyczna. Na czterech kolejnych pozycjach zapalić się mogą kolejno:

  • Z - zero
  • M - minus
  • C - przeniesienie
  • V - przepełnienie

Na przykład:

> emawp -d 0.0000000000000000000000001 1000000000000000000000000000000000000000
 in1:      OK  ----  0x7bcb 0x43d7 0x69ad  <-  0.000000000000000000000000100000000000000004
 in2:  OVFLOW  ----  0x5e0a 0x1fd2 0x7182  <-  999999999999999939709166371603178586112.000
 div:      OK  ----  0x543f 0xf513 0xd22c  ->  11579208923712.00000000000000000000000000000
> emawp -s 1 1
 in1:      OK  ----  0x4000 0x0000 0x0001  <-  1.000000000000000000000000000000000000000000
 in2:      OK  ----  0x4000 0x0000 0x0001  <-  1.000000000000000000000000000000000000000000
 sub:      OK  Z---  0x0000 0x0000 0x0000  ->  0.000000000000000000000000000000000000000000
> emawp -d 0.0000000000000000000000000000000000000001 100000000000000000000000000000000000
 in1:  UDFLOW  ----  0x45b0 0x989d 0xdd7c  <-  0.000000000000000000000000000000000000000100
 in2:      OK  ----  0x4d09 0x85cb 0x1d75  <-  99999999999999996863366107917975552.0000000
 div:      OK  ----  0x73ca 0xc65c 0x3907  ->  115.7920892371330410242080688476562500000000
> emawp -a -- -1.0 1
 in1:      OK  -M--  0x8000 0x0000 0x0000  <-  -1.000000000000000000000000000000000000000000
 in2:      OK  ----  0x4000 0x0000 0x0001  <-  1.000000000000000000000000000000000000000000
 add:      OK  Z---  0x0000 0x0000 0x0000  ->  0.000000000000000000000000000000000000000000