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
3c780c88 (kx 2024-12-29 12:21:01 +0300   1) .\" Copyright 2024 Andrew V.Kosteltsev (kx@radix-linux.su)
3c780c88 (kx 2024-12-29 12:21:01 +0300   2) .\"
3c780c88 (kx 2024-12-29 12:21:01 +0300   3) .\"
3c780c88 (kx 2024-12-29 12:21:01 +0300   4) .TH shifts 3  "December 27, 2024" "libmpu" "LibMPU Programmer's Manual"
3c780c88 (kx 2024-12-29 12:21:01 +0300   5) .SH NAME
3c780c88 (kx 2024-12-29 12:21:01 +0300   6) \fBishl\fP, \fBishr\fP, \fBisal\fP, \fBisar\fP \- операции сдвига на один бит
3c780c88 (kx 2024-12-29 12:21:01 +0300   7) .SH SYNOPSIS
3c780c88 (kx 2024-12-29 12:21:01 +0300   8) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300   9) .B #include <libmpu.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300  10) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  11) .BI "void ishl( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300  12) .BI "void ishr( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300  13) .BI "void isal( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300  14) .BI "void isar( mpu_int *" c ", mpu_int *" a ", int " nb " );
3c780c88 (kx 2024-12-29 12:21:01 +0300  15) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300  16) .SH DESCRIPTION
3c780c88 (kx 2024-12-29 12:21:01 +0300  17) Для операций сдвигов на один бит входным операндом служит переменная размером \fBnb\fP байт,
3c780c88 (kx 2024-12-29 12:21:01 +0300  18) находящаяся по адресу \fBa\fP, результат помещается в переменную того же размера,
3c780c88 (kx 2024-12-29 12:21:01 +0300  19) расположенную по адресу \fBc\fP. Пространства, занимаемые входной и выходной переменной
3c780c88 (kx 2024-12-29 12:21:01 +0300  20) в памяти могут пересекаться, как частично, так и полностью, что не влияет на правильность
3c780c88 (kx 2024-12-29 12:21:01 +0300  21) получаемого результата. Содержимое переменной, расположенной по адресу \fBa\fP останется
7ee94ee9 (kx 2024-12-30 20:56:27 +0300  22) неизменным, после выполнения операции, если занимаемое ею пространство не пересекается
3c780c88 (kx 2024-12-29 12:21:01 +0300  23) с пространством, занимаемым переменной \fBc\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300  24) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  25) При выполнениии операций сдвига, флаг переноса \fBC\fP всегда содержит значение последнего
3c780c88 (kx 2024-12-29 12:21:01 +0300  26) выдвинутого бита. Существуют следующие виды операций сдвига:
3c780c88 (kx 2024-12-29 12:21:01 +0300  27) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  28) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300  29)     SHL \- логический беззнаковый сдвиг влево на один бит.
3c780c88 (kx 2024-12-29 12:21:01 +0300  30) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300  31) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300  32)     SHR \- логический беззнаковый сдвиг вправо на один бит.
3c780c88 (kx 2024-12-29 12:21:01 +0300  33) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300  34) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300  35)     SAL \- арифметический сдвиг влево на один бит.
3c780c88 (kx 2024-12-29 12:21:01 +0300  36) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300  37) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300  38)     SAR \- арифметический сдвиг вправо на один бит.
3c780c88 (kx 2024-12-29 12:21:01 +0300  39) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300  40) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  41) Следующие таблицы иллюстрируют выполнение операций \fBishl\fP, \fBishr\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300  42) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300  43) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300  44)       ┌────────────────┬───┬───────────────────┬────────────┐
3c780c88 (kx 2024-12-29 12:21:01 +0300  45)       │ SHL(<<):       │ C │ значение операнда │ заполнение │
3c780c88 (kx 2024-12-29 12:21:01 +0300  46)       ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  47)       │ до операции    │   │      10110111     │     0      │
3c780c88 (kx 2024-12-29 12:21:01 +0300  48)       ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  49)       │ после операции │ 1 │      01101110     │            │
3c780c88 (kx 2024-12-29 12:21:01 +0300  50)       └────────────────┴───┴───────────────────┴────────────┘
3c780c88 (kx 2024-12-29 12:21:01 +0300  51) 
3c780c88 (kx 2024-12-29 12:21:01 +0300  52)       ┌────────────────┬────────────┬───────────────────┬───┐
3c780c88 (kx 2024-12-29 12:21:01 +0300  53)       │ SHR(>>):       │ заполнение │ значение операнда │ C │
3c780c88 (kx 2024-12-29 12:21:01 +0300  54)       ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  55)       │ до операции    │     0      │      10110111     │   │
3c780c88 (kx 2024-12-29 12:21:01 +0300  56)       ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  57)       │ после операции │            │      01011011     │ 1 │
3c780c88 (kx 2024-12-29 12:21:01 +0300  58)       └────────────────┴────────────┴───────────────────┴───┘
3c780c88 (kx 2024-12-29 12:21:01 +0300  59) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300  60) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300  61) Из таблиц видно, что при любом логическом сдвиге на освободившееся место всегда задвигается 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300  62) Флаг переполнения \fBO\fP выставляется, если в результате операции операнд изменил знак.
3c780c88 (kx 2024-12-29 12:21:01 +0300  63) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  64) Операция арифметического сдвига влево \fBisal\fP действует аналогично операции \fBishl\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300  65) (также на пустое место справа задвигается 0). Операция арифметического сдвига вправо действует
3c780c88 (kx 2024-12-29 12:21:01 +0300  66) иначе: в освобождающуюся позицию слева копируется знаковый бит исходного операнда.
3c780c88 (kx 2024-12-29 12:21:01 +0300  67) Действие операций \fBisal\fP и \fBisar\fP показано с помощью следующих таблиц.
3c780c88 (kx 2024-12-29 12:21:01 +0300  68) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300  69) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300  70)       ┌────────────────┬───┬───────────────────┬────────────┐
3c780c88 (kx 2024-12-29 12:21:01 +0300  71)       │ SAL(<<):       │ C │ значение операнда │ заполнение │
3c780c88 (kx 2024-12-29 12:21:01 +0300  72)       ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  73)       │ до операции    │   │      10110111     │     0      │
3c780c88 (kx 2024-12-29 12:21:01 +0300  74)       ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  75)       │ после операции │ 1 │      01101110     │            │
3c780c88 (kx 2024-12-29 12:21:01 +0300  76)       └────────────────┴───┴───────────────────┴────────────┘
3c780c88 (kx 2024-12-29 12:21:01 +0300  77) 
3c780c88 (kx 2024-12-29 12:21:01 +0300  78)       ┌────────────────┬────────────┬───────────────────┬───┐
3c780c88 (kx 2024-12-29 12:21:01 +0300  79)       │ SAR(>>):       │ заполнение │ значение операнда │ C │
3c780c88 (kx 2024-12-29 12:21:01 +0300  80)       ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  81)       │ до операции    │   sign(1)  │      10110111     │   │
3c780c88 (kx 2024-12-29 12:21:01 +0300  82)       ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  83)       │ после операции │            │      11011011     │ 1 │
3c780c88 (kx 2024-12-29 12:21:01 +0300  84)       └────────────────┴────────────┴───────────────────┴───┘
3c780c88 (kx 2024-12-29 12:21:01 +0300  85) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300  86) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300  87) Флаг переполнения при выполнении операции \fBisal\fP выставляется таким же образом, как
3c780c88 (kx 2024-12-29 12:21:01 +0300  88) и при операции \fBishl\fP. При выполнении операции \fBisar\fP, операнд не может изменить
3c780c88 (kx 2024-12-29 12:21:01 +0300  89) свой знак. Многократный сдвиг \fBisar\fP может, в конце концов, привести к потере значения,
3c780c88 (kx 2024-12-29 12:21:01 +0300  90) и положительное число задвинется в 0, а отрицательное в -1. По этому флаг переполнения \fBO\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300  91) для операции \fBisar\fP сбрасывается в 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300  92) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  93) При выполнении операций \fBisal\fP, \fBisar\fP, \fBishl\fP, \fBishr\fP, так же выставляются
3c780c88 (kx 2024-12-29 12:21:01 +0300  94) флаги четности \fBP\fP, знака \fBS\fP и нуля \fBZ\fP. Флаг переноса из младшей тетрады \fBA\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300  95) не определяется и просто сбрасывается в 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300  96) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  97) Сдвиг влево можно применять для удваивания чисел, а сдвиг вправо \- для деления на 2. Эти операции
3c780c88 (kx 2024-12-29 12:21:01 +0300  98) выполняются значительно быстрее, чем операции умножения и деления. Деление пополам нечетных чисел
3c780c88 (kx 2024-12-29 12:21:01 +0300  99) (например, 5 или 7) образует меньшие значения (2 или 3, соответственно) и устанавливает флаг
3c780c88 (kx 2024-12-29 12:21:01 +0300 100) переноса \fBC\fP в 1. При этом \fBC\fP, фактически, содержит остаток от деления. Такое использование
3c780c88 (kx 2024-12-29 12:21:01 +0300 101) операций сдвига требует контроля за флагом переполнения \fBO\fP. Для простоты, рассмотрим контроль
3c780c88 (kx 2024-12-29 12:21:01 +0300 102) флагов на 4\-битных знаковых переменных:
3c780c88 (kx 2024-12-29 12:21:01 +0300 103) .SS Примеры с 4\-битными операндами:
3c780c88 (kx 2024-12-29 12:21:01 +0300 104) \fBУмножение на 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 105) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 106) SAL(0111) =  7; результат = 1110 = -2, ошибка, должно быть 14, CF = 0, OF = 1
3c780c88 (kx 2024-12-29 12:21:01 +0300 107) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 108) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 109) \fBДеление на 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 110) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 111) SHR(1000) = -8; результат = 0100 =  4, ошибка, должно быть -4, CF = 0, OF = 1
3c780c88 (kx 2024-12-29 12:21:01 +0300 112) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 113) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 114) \fBДеление на 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 115) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 116) SAR(1000) = -8; результат = 1100 = -4, абсолютно точно, CF = 0, OF = 0
3c780c88 (kx 2024-12-29 12:21:01 +0300 117) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 118) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 119) \fBДеление на 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 120) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 121) SAR(0111) =  7; результат = 0011 =  3, остаток 1 (см. флаг C), абсолютно точно, CF = 1, OF = 0
3c780c88 (kx 2024-12-29 12:21:01 +0300 122) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 123) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 124) .SH EXAMPLES
3c780c88 (kx 2024-12-29 12:21:01 +0300 125) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 126) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 127) #include <libmpu.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 128) #include <stdio.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 129) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 130) int main( void )
3c780c88 (kx 2024-12-29 12:21:01 +0300 131) {
3c780c88 (kx 2024-12-29 12:21:01 +0300 132)   int  rc = 0;
3c780c88 (kx 2024-12-29 12:21:01 +0300 133) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 134)   __mpu_init();
3c780c88 (kx 2024-12-29 12:21:01 +0300 135)   __mpu_extra_warnings = 1;
3c780c88 (kx 2024-12-29 12:21:01 +0300 136) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 137)   {
1ca800d6 (kx 2024-12-29 20:12:16 +0300 138)     mpu_int8_t     c, a;
3c780c88 (kx 2024-12-29 12:21:01 +0300 139)     int            nb = NB_I8;
3c780c88 (kx 2024-12-29 12:21:01 +0300 140)     __mpu_char8_t  sc[32], sa[32];
3c780c88 (kx 2024-12-29 12:21:01 +0300 141) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 142)     iatoi( a, "0b10110111", nb ); /* evaluate the A variable */
3c780c88 (kx 2024-12-29 12:21:01 +0300 143) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 144)     ishl( c, a, nb );
3c780c88 (kx 2024-12-29 12:21:01 +0300 145)     iitoa( sa, a, RADIX_BIN, LOWERCASE, nb ); /* convert A value to ASCII string SA */
3c780c88 (kx 2024-12-29 12:21:01 +0300 146)     iitoa( sc, c, RADIX_BIN, LOWERCASE, nb ); /* convert C value to ASCII string SC */
e3f8685d (kx 2024-12-30 18:22:24 +0300 147)     printf( "a = %s;\\n", sa ); /* c = 0b10110111; */
e3f8685d (kx 2024-12-30 18:22:24 +0300 148)     printf( "c = %s;\\n", sc ); /* c = 0b01101110; */
e3f8685d (kx 2024-12-30 18:22:24 +0300 149)     printf( "carry      = %d;\\n", __mpu_gtc() );  /* Carry Flag    */
e3f8685d (kx 2024-12-30 18:22:24 +0300 150)     printf( "overflow   = %d;\\n", __mpu_gto() );  /* Overflow Flag */
3c780c88 (kx 2024-12-29 12:21:01 +0300 151)   }
3c780c88 (kx 2024-12-29 12:21:01 +0300 152) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 153)   __mpu_free_context();
3c780c88 (kx 2024-12-29 12:21:01 +0300 154) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 155)   return( rc );
3c780c88 (kx 2024-12-29 12:21:01 +0300 156) }
3c780c88 (kx 2024-12-29 12:21:01 +0300 157) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 158) .SH SEE ALSO
3c780c88 (kx 2024-12-29 12:21:01 +0300 159) .BR iadd(3),
3c780c88 (kx 2024-12-29 12:21:01 +0300 160) .BR isub(3),
41c271da (kx 2025-01-05 15:42:39 +0300 161) .BR iadc(3),
41c271da (kx 2025-01-05 15:42:39 +0300 162) .BR isbb(3),
41c271da (kx 2025-01-05 15:42:39 +0300 163) .BR irol(3),
41c271da (kx 2025-01-05 15:42:39 +0300 164) .BR iror(3),
41c271da (kx 2025-01-05 15:42:39 +0300 165) .BR ircl(3),
41c271da (kx 2025-01-05 15:42:39 +0300 166) .BR ircr(3),
41c271da (kx 2025-01-05 15:42:39 +0300 167) .BR ishln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 168) .BR ishrn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 169) .BR isaln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 170) .BR isarn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 171) .BR iroln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 172) .BR irorn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 173) .BR ircln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 174) .BR ircrn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 175) .BR ineg(3),
41c271da (kx 2025-01-05 15:42:39 +0300 176) .BR inot(3),
41c271da (kx 2025-01-05 15:42:39 +0300 177) .BR iand(3),
41c271da (kx 2025-01-05 15:42:39 +0300 178) .BR itest(3),
41c271da (kx 2025-01-05 15:42:39 +0300 179) .BR icmp(3),
41c271da (kx 2025-01-05 15:42:39 +0300 180) .BR ior(3),
41c271da (kx 2025-01-05 15:42:39 +0300 181) .BR ixor(3),
41c271da (kx 2025-01-05 15:42:39 +0300 182) .BR iinc(3),
41c271da (kx 2025-01-05 15:42:39 +0300 183) .BR idec(3),
41c271da (kx 2025-01-05 15:42:39 +0300 184) .BR ixchg(3),
41c271da (kx 2025-01-05 15:42:39 +0300 185) .BR icpy(3),
41c271da (kx 2025-01-05 15:42:39 +0300 186) .BR icvt(3),
41c271da (kx 2025-01-05 15:42:39 +0300 187) .BR imul(3),
41c271da (kx 2025-01-05 15:42:39 +0300 188) .BR ismul(3),
41c271da (kx 2025-01-05 15:42:39 +0300 189) .BR idiv(3),
41c271da (kx 2025-01-05 15:42:39 +0300 190) .BR isdiv(3),
41c271da (kx 2025-01-05 15:42:39 +0300 191) .BR iatoi(3),
41c271da (kx 2025-01-05 15:42:39 +0300 192) .BR iatoui(3),
41c271da (kx 2025-01-05 15:42:39 +0300 193) .BR iitoa(3),
41c271da (kx 2025-01-05 15:42:39 +0300 194) .BR iuitoa(3).