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 \- one\-bit shifts
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) For one\-bit shift operations, the input operand is a variable of size \fBnb\fP bytes located
3c780c88 (kx 2024-12-29 12:21:01 +0300  18) at address \fBa\fP, the result is placed in a variable of the same size located at address \fBc\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300  19) The spaces occupied by the input and output variable in memory may overlap, either partially or
3c780c88 (kx 2024-12-29 12:21:01 +0300  20) completely, which does not affect the correctness of the result obtained. The content of the
3c780c88 (kx 2024-12-29 12:21:01 +0300  21) variable located at address \fBa\fP will remain unchanged after the operation if the space
3c780c88 (kx 2024-12-29 12:21:01 +0300  22) occupied by it does not overlap with the space occupied by variable \fBc\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300  23) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  24) When performing shift operations, the carry flag \fBC\fP always contains the value of the last
af4d4942 (kx 2024-12-30 12:16:19 +0300  25) pushed outward bit. There are the following types of shift operations:
3c780c88 (kx 2024-12-29 12:21:01 +0300  26) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  27) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300  28)     SHL \- logical unsigned shift to the left by one bit.
3c780c88 (kx 2024-12-29 12:21:01 +0300  29) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300  30) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300  31)     SHR \- logical unsigned shift to the right by one bit.
3c780c88 (kx 2024-12-29 12:21:01 +0300  32) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300  33) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300  34)     SAL \- arithmetic shift to the left by one bit.
3c780c88 (kx 2024-12-29 12:21:01 +0300  35) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300  36) .RS 3
3c780c88 (kx 2024-12-29 12:21:01 +0300  37)     SAR \- arithmetic shift to the right by one bit.
3c780c88 (kx 2024-12-29 12:21:01 +0300  38) .RE
3c780c88 (kx 2024-12-29 12:21:01 +0300  39) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  40) The following tables illustrate the execution of the operations \fBishl\fP, \fBishr\fP.
3c780c88 (kx 2024-12-29 12:21:01 +0300  41) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300  42) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300  43)       ┌────────────────┬───┬───────────────────┬────────────┐
3c780c88 (kx 2024-12-29 12:21:01 +0300  44)       │ SHL(<<):       │ C │   operand value   │  filling   │
3c780c88 (kx 2024-12-29 12:21:01 +0300  45)       ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  46)       │ before         │   │      10110111     │     0      │
3c780c88 (kx 2024-12-29 12:21:01 +0300  47)       ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  48)       │ after          │ 1 │      01101110     │            │
3c780c88 (kx 2024-12-29 12:21:01 +0300  49)       └────────────────┴───┴───────────────────┴────────────┘
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)       │ SHR(>>):       │  filling   │   operand value   │ C │
3c780c88 (kx 2024-12-29 12:21:01 +0300  53)       ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  54)       │ before         │     0      │      10110111     │   │
3c780c88 (kx 2024-12-29 12:21:01 +0300  55)       ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  56)       │ after          │            │      01011011     │ 1 │
3c780c88 (kx 2024-12-29 12:21:01 +0300  57)       └────────────────┴────────────┴───────────────────┴───┘
3c780c88 (kx 2024-12-29 12:21:01 +0300  58) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300  59) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300  60) The tables show that any logical shift always results in a 0 being pushed into the vacated space. 
3c780c88 (kx 2024-12-29 12:21:01 +0300  61) The overflow flag \fBO\fP is set if the operand has changed sign as a result of the operation.
3c780c88 (kx 2024-12-29 12:21:01 +0300  62) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  63) The left arithmetic shift operation \fBisal\fP operates in the same way as \fBishl\fP (0 is
3c780c88 (kx 2024-12-29 12:21:01 +0300  64) also moved to the empty space on the right). The right arithmetic shift operation works
3c780c88 (kx 2024-12-29 12:21:01 +0300  65) differently: the sign bit of the original operand is copied to the empty position on the left.
3c780c88 (kx 2024-12-29 12:21:01 +0300  66) The action of the \fBisal\fP and \fBisar\fP operations is shown in the following tables.
3c780c88 (kx 2024-12-29 12:21:01 +0300  67) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300  68) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300  69)       ┌────────────────┬───┬───────────────────┬────────────┐
3c780c88 (kx 2024-12-29 12:21:01 +0300  70)       │ SAL(<<):       │ C │   operand value   │  filling   │
3c780c88 (kx 2024-12-29 12:21:01 +0300  71)       ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  72)       │ before         │   │      10110111     │     0      │
3c780c88 (kx 2024-12-29 12:21:01 +0300  73)       ├────────────────┼───┼───────────────────┼────────────┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  74)       │ after          │ 1 │      01101110     │            │
3c780c88 (kx 2024-12-29 12:21:01 +0300  75)       └────────────────┴───┴───────────────────┴────────────┘
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)       │ SAR(>>):       │  filling   │   operand value   │ C │
3c780c88 (kx 2024-12-29 12:21:01 +0300  79)       ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  80)       │ before         │   sign(1)  │      10110111     │   │
3c780c88 (kx 2024-12-29 12:21:01 +0300  81)       ├────────────────┼────────────┼───────────────────┼───┤
3c780c88 (kx 2024-12-29 12:21:01 +0300  82)       │ after          │            │      11011011     │ 1 │
3c780c88 (kx 2024-12-29 12:21:01 +0300  83)       └────────────────┴────────────┴───────────────────┴───┘
3c780c88 (kx 2024-12-29 12:21:01 +0300  84) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300  85) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300  86) The overflow flag for the \fBisal\fP operation is set in the same way as for the \fBishl\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300  87) operation. When performing an \fBisar\fP operation, the operand cannot change its sign. Repeated
3c780c88 (kx 2024-12-29 12:21:01 +0300  88) shifting of \fBisar\fP may eventually cause a loss of value, and a positive number will be shifted
3c780c88 (kx 2024-12-29 12:21:01 +0300  89) to 0 and a negative number to -1. Therefore, the overflow flag \fBO\fP for the \fBisar\fP operation
3c780c88 (kx 2024-12-29 12:21:01 +0300  90) is reset to 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300  91) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  92) When performing \fBisal\fP, \fBisar\fP, \fBishl\fP, \fBishr\fP operations, the parity \fBP\fP,
3c780c88 (kx 2024-12-29 12:21:01 +0300  93) sign \fBS\fP and zero \fBZ\fP flags are also set. The carry flag from the lowest tetrad \fBA\fP
3c780c88 (kx 2024-12-29 12:21:01 +0300  94) is not defined and is simply reset to 0.
3c780c88 (kx 2024-12-29 12:21:01 +0300  95) .PP
3c780c88 (kx 2024-12-29 12:21:01 +0300  96) Left shift can be used to double numbers, and right shift can be used to divide by 2. These operations
3c780c88 (kx 2024-12-29 12:21:01 +0300  97) are much faster than multiplication and division operations. Dividing odd numbers (such as 5 or 7) in
3c780c88 (kx 2024-12-29 12:21:01 +0300  98) half forms smaller values (2 or 3, respectively) and sets the carry flag \fBC\fP to 1. In doing so,
3c780c88 (kx 2024-12-29 12:21:01 +0300  99) \fBC\fP actually contains the remainder of the division. This use of shift operations requires control
3c780c88 (kx 2024-12-29 12:21:01 +0300 100) of the overflow flag \fBO\fP. For simplicity, consider flag control on 4\-bit signed variables:
3c780c88 (kx 2024-12-29 12:21:01 +0300 101) .SS Examples with 4\-bit operands:
3c780c88 (kx 2024-12-29 12:21:01 +0300 102) \fBMultiplying by 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 103) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 104) SAL(0111) =  7; result = 1110 = -2, mistake, there must be 14, CF = 0, OF = 1
3c780c88 (kx 2024-12-29 12:21:01 +0300 105) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 106) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 107) \fBDividing by 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 108) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 109) SHR(1000) = -8; result = 0100 =  4, mistake, there must be -4, CF = 0, OF = 1
3c780c88 (kx 2024-12-29 12:21:01 +0300 110) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 111) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 112) \fBDividing by 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 113) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 114) SAR(1000) = -8; result = 1100 = -4, exactly, CF = 0, OF = 0
3c780c88 (kx 2024-12-29 12:21:01 +0300 115) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 116) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 117) \fBDividing by 2\fP:
3c780c88 (kx 2024-12-29 12:21:01 +0300 118) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 119) SAR(0111) =  7; result = 0011 =  3, remainder 1 (see carry flag C), exactly, CF = 1, OF = 0
3c780c88 (kx 2024-12-29 12:21:01 +0300 120) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 121) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 122) .SH EXAMPLES
3c780c88 (kx 2024-12-29 12:21:01 +0300 123) .nf
3c780c88 (kx 2024-12-29 12:21:01 +0300 124) .sp
3c780c88 (kx 2024-12-29 12:21:01 +0300 125) #include <libmpu.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 126) #include <stdio.h>
3c780c88 (kx 2024-12-29 12:21:01 +0300 127) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 128) int main( void )
3c780c88 (kx 2024-12-29 12:21:01 +0300 129) {
3c780c88 (kx 2024-12-29 12:21:01 +0300 130)   int  rc = 0;
3c780c88 (kx 2024-12-29 12:21:01 +0300 131) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 132)   __mpu_init();
3c780c88 (kx 2024-12-29 12:21:01 +0300 133)   __mpu_extra_warnings = 1;
3c780c88 (kx 2024-12-29 12:21:01 +0300 134) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 135)   {
1ca800d6 (kx 2024-12-29 20:12:16 +0300 136)     mpu_int8_t     c, a;
3c780c88 (kx 2024-12-29 12:21:01 +0300 137)     int            nb = NB_I8;
3c780c88 (kx 2024-12-29 12:21:01 +0300 138)     __mpu_char8_t  sc[32], sa[32];
3c780c88 (kx 2024-12-29 12:21:01 +0300 139) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 140)     iatoi( a, "0b10110111", nb ); /* evaluate the A variable */
3c780c88 (kx 2024-12-29 12:21:01 +0300 141) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 142)     ishl( c, a, nb );
3c780c88 (kx 2024-12-29 12:21:01 +0300 143)     iitoa( sa, a, RADIX_BIN, LOWERCASE, nb ); /* convert A value to ASCII string SA */
3c780c88 (kx 2024-12-29 12:21:01 +0300 144)     iitoa( sc, c, RADIX_BIN, LOWERCASE, nb ); /* convert C value to ASCII string SC */
e3f8685d (kx 2024-12-30 18:22:24 +0300 145)     printf( "a = %s;\\n", sa ); /* c = 0b10110111; */
e3f8685d (kx 2024-12-30 18:22:24 +0300 146)     printf( "c = %s;\\n", sc ); /* c = 0b01101110; */
e3f8685d (kx 2024-12-30 18:22:24 +0300 147)     printf( "carry      = %d;\\n", __mpu_gtc() );  /* Carry Flag    */
e3f8685d (kx 2024-12-30 18:22:24 +0300 148)     printf( "overflow   = %d;\\n", __mpu_gto() );  /* Overflow Flag */
3c780c88 (kx 2024-12-29 12:21:01 +0300 149)   }
3c780c88 (kx 2024-12-29 12:21:01 +0300 150) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 151)   __mpu_free_context();
3c780c88 (kx 2024-12-29 12:21:01 +0300 152) 
3c780c88 (kx 2024-12-29 12:21:01 +0300 153)   return( rc );
3c780c88 (kx 2024-12-29 12:21:01 +0300 154) }
3c780c88 (kx 2024-12-29 12:21:01 +0300 155) .fi
3c780c88 (kx 2024-12-29 12:21:01 +0300 156) .SH SEE ALSO
3c780c88 (kx 2024-12-29 12:21:01 +0300 157) .BR iadd(3),
3c780c88 (kx 2024-12-29 12:21:01 +0300 158) .BR isub(3),
41c271da (kx 2025-01-05 15:42:39 +0300 159) .BR iadc(3),
41c271da (kx 2025-01-05 15:42:39 +0300 160) .BR isbb(3),
41c271da (kx 2025-01-05 15:42:39 +0300 161) .BR irol(3),
41c271da (kx 2025-01-05 15:42:39 +0300 162) .BR iror(3),
41c271da (kx 2025-01-05 15:42:39 +0300 163) .BR ircl(3),
41c271da (kx 2025-01-05 15:42:39 +0300 164) .BR ircr(3),
41c271da (kx 2025-01-05 15:42:39 +0300 165) .BR ishln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 166) .BR ishrn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 167) .BR isaln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 168) .BR isarn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 169) .BR iroln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 170) .BR irorn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 171) .BR ircln(3),
41c271da (kx 2025-01-05 15:42:39 +0300 172) .BR ircrn(3),
41c271da (kx 2025-01-05 15:42:39 +0300 173) .BR ineg(3),
41c271da (kx 2025-01-05 15:42:39 +0300 174) .BR inot(3),
41c271da (kx 2025-01-05 15:42:39 +0300 175) .BR iand(3),
41c271da (kx 2025-01-05 15:42:39 +0300 176) .BR itest(3),
41c271da (kx 2025-01-05 15:42:39 +0300 177) .BR icmp(3),
41c271da (kx 2025-01-05 15:42:39 +0300 178) .BR ior(3),
41c271da (kx 2025-01-05 15:42:39 +0300 179) .BR ixor(3),
41c271da (kx 2025-01-05 15:42:39 +0300 180) .BR iinc(3),
41c271da (kx 2025-01-05 15:42:39 +0300 181) .BR idec(3),
41c271da (kx 2025-01-05 15:42:39 +0300 182) .BR ixchg(3),
41c271da (kx 2025-01-05 15:42:39 +0300 183) .BR icpy(3),
41c271da (kx 2025-01-05 15:42:39 +0300 184) .BR icvt(3),
41c271da (kx 2025-01-05 15:42:39 +0300 185) .BR imul(3),
41c271da (kx 2025-01-05 15:42:39 +0300 186) .BR ismul(3),
41c271da (kx 2025-01-05 15:42:39 +0300 187) .BR idiv(3),
41c271da (kx 2025-01-05 15:42:39 +0300 188) .BR isdiv(3),
41c271da (kx 2025-01-05 15:42:39 +0300 189) .BR iatoi(3),
41c271da (kx 2025-01-05 15:42:39 +0300 190) .BR iatoui(3),
41c271da (kx 2025-01-05 15:42:39 +0300 191) .BR iitoa(3),
41c271da (kx 2025-01-05 15:42:39 +0300 192) .BR iuitoa(3).