Math Processor Unit Library

libmpu – library of arithmetic functions for integer, real, and complex numbers of increased digit capacity

16 Commits   0 Branches   2 Tags
author: kx <kx@radix-linux.su> 2024-12-29 12:21:01 +0300 committer: kx <kx@radix-linux.su> 2024-12-29 12:21:01 +0300 commit: 3c780c88a0a0e98f7bb1ceaf7843c4560d2e0ce4 parent: 31f615c1e5a07398bdd68c74b81fbe64c45f169a
Commit Summary:
Man pages for one-bit shift operations
Diffstat:
6 files changed, 161 insertions, 1 deletion
diff --git a/man/ru/Makefile.am b/man/ru/Makefile.am
index eedea05..f397efa 100644
--- a/man/ru/Makefile.am
+++ b/man/ru/Makefile.am
@@ -4,7 +4,10 @@ LANG = ru
 mandir = @mandir@/$(LANG)
 
 MAN3 = iadc.3mpu iadd.3mpu \
-       isbb.3mpu isub.3mpu
+       isbb.3mpu isub.3mpu \
+       shifts.3mpu \
+       isal.3mpu isar.3mpu \
+       ishl.3mpu ishr.3mpu
 
 MAN7 = libmpu.7
 
diff --git a/man/ru/isal.3mpu b/man/ru/isal.3mpu
new file mode 100644
index 0000000..1957f71
--- /dev/null
+++ b/man/ru/isal.3mpu
@@ -0,0 +1 @@
+.so man3/shifts.3mpu
diff --git a/man/ru/isar.3mpu b/man/ru/isar.3mpu
new file mode 100644
index 0000000..1957f71
--- /dev/null
+++ b/man/ru/isar.3mpu
@@ -0,0 +1 @@
+.so man3/shifts.3mpu
diff --git a/man/ru/ishl.3mpu b/man/ru/ishl.3mpu
new file mode 100644
index 0000000..1957f71
--- /dev/null
+++ b/man/ru/ishl.3mpu
@@ -0,0 +1 @@
+.so man3/shifts.3mpu
diff --git a/man/ru/ishr.3mpu b/man/ru/ishr.3mpu
new file mode 100644
index 0000000..1957f71
--- /dev/null
+++ b/man/ru/ishr.3mpu
@@ -0,0 +1 @@
+.so man3/shifts.3mpu
diff --git a/man/ru/shifts.3mpu b/man/ru/shifts.3mpu
new file mode 100644
index 0000000..3252b01
--- /dev/null
+++ b/man/ru/shifts.3mpu
@@ -0,0 +1,165 @@
+.\" Copyright 2024 Andrew V.Kosteltsev (kx@radix-linux.su)
+.\"
+.\"
+.TH shifts 3  "December 27, 2024" "libmpu" "LibMPU Programmer's Manual"
+.SH NAME
+\fBishl\fP, \fBishr\fP, \fBisal\fP, \fBisar\fP \- операции сдвига на один бит
+.SH SYNOPSIS
+.nf
+.B #include <libmpu.h>
+.PP
+.BI "void ishl( mpu_int *" c ", mpu_int *" a ", int " nb " );
+.BI "void ishr( mpu_int *" c ", mpu_int *" a ", int " nb " );
+.BI "void isal( mpu_int *" c ", mpu_int *" a ", int " nb " );
+.BI "void isar( mpu_int *" c ", mpu_int *" a ", int " nb " );
+.fi
+.SH DESCRIPTION
+Для операций сдвигов на один бит входным операндом служит переменная размером \fBnb\fP байт,
+находящаяся по адресу \fBa\fP, результат помещается в переменную того же размера,
+расположенную по адресу \fBc\fP. Пространства, занимаемые входной и выходной переменной
+в памяти могут пересекаться, как частично, так и полностью, что не влияет на правильность
+получаемого результата. Содержимое переменной, расположенной по адресу \fBa\fP останется
+неизменным, после выполнения операции, если занимаемое ей пространство не пересекается
+с пространством, занимаемым переменной \fBc\fP.
+.PP
+При выполнениии операций сдвига, флаг переноса \fBC\fP всегда содержит значение последнего
+выдвинутого бита. Существуют следующие виды операций сдвига:
+.PP
+
+.RS 3
+    SHL \- логический беззнаковый сдвиг влево на один бит.
+.RE
+.RS 3
+    SHR \- логический беззнаковый сдвиг вправо на один бит.
+.RE
+.RS 3
+    SAL \- арифметический сдвиг влево на один бит.
+.RE
+.RS 3
+    SAR \- арифметический сдвиг вправо на один бит.
+.RE
+
+.PP
+Следующие таблицы иллюстрируют выполнение операций \fBishl\fP, \fBishr\fP.
+.nf
+.sp
+      ┌────────────────┬───┬───────────────────┬────────────┐
+      │ SHL(<<):       │ C │ значение операнда │ заполнение │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ до операции    │   │      10110111     │     0      │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ после операции │ 1 │      01101110     │            │
+      └────────────────┴───┴───────────────────┴────────────┘
+
+      ┌────────────────┬────────────┬───────────────────┬───┐
+      │ SHR(>>):       │ заполнение │ значение операнда │ C │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ до операции    │     0      │      10110111     │   │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ после операции │            │      01011011     │ 1 │
+      └────────────────┴────────────┴───────────────────┴───┘
+.fi
+.sp
+Из таблиц видно, что при любом логическом сдвиге на освободившееся место всегда задвигается 0.
+Флаг переполнения \fBO\fP выставляется, если в результате операции операнд изменил знак.
+.PP
+Операция арифметического сдвига влево \fBisal\fP действует аналогично операции \fBishl\fP
+(также на пустое место справа задвигается 0). Операция арифметического сдвига вправо действует
+иначе: в освобождающуюся позицию слева копируется знаковый бит исходного операнда.
+Действие операций \fBisal\fP и \fBisar\fP показано с помощью следующих таблиц.
+.nf
+.sp
+      ┌────────────────┬───┬───────────────────┬────────────┐
+      │ SAL(<<):       │ C │ значение операнда │ заполнение │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ до операции    │   │      10110111     │     0      │
+      ├────────────────┼───┼───────────────────┼────────────┤
+      │ после операции │ 1 │      01101110     │            │
+      └────────────────┴───┴───────────────────┴────────────┘
+
+      ┌────────────────┬────────────┬───────────────────┬───┐
+      │ SAR(>>):       │ заполнение │ значение операнда │ C │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ до операции    │   sign(1)  │      10110111     │   │
+      ├────────────────┼────────────┼───────────────────┼───┤
+      │ после операции │            │      11011011     │ 1 │
+      └────────────────┴────────────┴───────────────────┴───┘
+.fi
+.sp
+Флаг переполнения при выполнении операции \fBisal\fP выставляется таким же образом, как
+и при операции \fBishl\fP. При выполнении операции \fBisar\fP, операнд не может изменить
+свой знак. Многократный сдвиг \fBisar\fP может, в конце концов, привести к потере значения,
+и положительное число задвинется в 0, а отрицательное в -1. По этому флаг переполнения \fBO\fP
+для операции \fBisar\fP сбрасывается в 0.
+.PP
+При выполнении операций \fBisal\fP, \fBisar\fP, \fBishl\fP, \fBishr\fP, так же выставляются
+флаги четности \fBP\fP, знака \fBS\fP и нуля \fBZ\fP. Флаг переноса из младшей тетрады \fBA\fP
+не определяется и просто сбрасывается в 0.
+.PP
+Сдвиг влево можно применять для удваивания чисел, а сдвиг вправо \- для деления на 2. Эти операции
+выполняются значительно быстрее, чем операции умножения и деления. Деление пополам нечетных чисел
+(например, 5 или 7) образует меньшие значения (2 или 3, соответственно) и устанавливает флаг
+переноса \fBC\fP в 1. При этом \fBC\fP, фактически, содержит остаток от деления. Такое использование
+операций сдвига требует контроля за флагом переполнения \fBO\fP. Для простоты, рассмотрим контроль
+флагов на 4\-битных знаковых переменных:
+.SS Примеры с 4\-битными операндами:
+\fBУмножение на 2\fP:
+.nf
+SAL(0111) =  7; результат = 1110 = -2, ошибка, должно быть 14, CF = 0, OF = 1
+.fi
+.sp
+\fBДеление на 2\fP:
+.nf
+SHR(1000) = -8; результат = 0100 =  4, ошибка, должно быть -4, CF = 0, OF = 1
+.fi
+.sp
+\fBДеление на 2\fP:
+.nf
+SAR(1000) = -8; результат = 1100 = -4, абсолютно точно, CF = 0, OF = 0
+.fi
+.sp
+\fBДеление на 2\fP:
+.nf
+SAR(0111) =  7; результат = 0011 =  3, остаток 1 (см. флаг C), абсолютно точно, CF = 1, OF = 0
+.fi
+.sp
+.SH EXAMPLES
+.nf
+.sp
+#include <libmpu.h>
+#include <stdio.h>
+
+int main( void )
+{
+  int  rc = 0;
+
+  __mpu_init();
+  __mpu_extra_warnings = 1;
+
+  {
+    mpu_int128_t   c, a;
+    int            nb = NB_I8;
+    __mpu_char8_t  sc[32], sa[32];
+
+    iatoi( a, "0b10110111", nb ); /* evaluate the A variable */
+
+    ishl( c, a, nb );
+    iitoa( sa, a, RADIX_BIN, LOWERCASE, nb ); /* convert A value to ASCII string SA */
+    iitoa( sc, c, RADIX_BIN, LOWERCASE, nb ); /* convert C value to ASCII string SC */
+    printf( "a = %s;\n", sa ); /* c = 0b10110111; */
+    printf( "c = %s;\n", sc ); /* c = 0b01101110; */
+    printf( "carry      = %d;\n", __mpu_gtc() );  /* Carry Flag    */
+    printf( "overflow   = %d;\n", __mpu_gto() );  /* Overflow Flag */
+  }
+
+  __mpu_free_context();
+
+  return( rc );
+}
+.fi
+.SH SEE ALSO
+.BR iadd(3),
+.BR iadc(3),
+.BR isub(3),
+.BR isbb(3).
+