chsvlib
chsv helper source code

◆ memdiv_BE()

chsverror_t Chusov::Memory::memdiv_BE ( const void *restrict  pDividend,
std::size_t  cbDividend,
const void *restrict  pDivisor,
std::size_t  cbDivisor,
void *restrict  pQuotient,
std::size_t  cbQuotient,
void *restrict  pRemainder,
std::size_t  cbRemainder 
)
noexcept

Performs Euclidean division of two arbitrary-precision integers specified with vectors of bytes in the Big-Endian order and produces an arbitrary-precision quotient and remainder.

Parameters
[in]pDividendA pointer to an unsigned dividend.
cbDividendA byte size of the dividend pointed to by pDividend.
[in]pDivisorA pointer to an unsigned divisor.
cbDivisorSize of the divisor in bytes.
[out]pQuotientAn optional pointer to a buffer which receives a quotient resulting from the division rounded down toward zero. If the capacity of the buffer is less than max(cbDividend - cbDivisor + 1, 1) the actual Euclidean quotient is truncated to fit the capacity of cbQuotient bytes. Particularly, if cbQuotient is zero, then no quotient is returned to caller. On the other hand, if the capacity is greater than max(cbDividend - cbDivisor + 1, 1), the actual quotient is zero-extended within the output buffer to fill cbQuotient bytes of space.
cbQuotientA byte capacity of the quotient buffer pointed to by pQuotient and a byte size of the resulting quotient calculated modulo bcbQuotient, where b = 2CHAR_BIT is a number of values that one byte can represent. No quotient is returned, if cbQuotient is zero, in which case pQuotient may be equal to nullptr.
[out]pRemainderAn optional pointer to a buffer which on output receives the remainder of the division modulo bcbRemainder. That is, if cbRemainder < cbDivisor, the actual remainder is truncated to fit the cbRemainder capacity. Particularly, if cbRemainder is zero, no remainder is returned by the function. Conversely, if cbRemainder > cbDivisor, the actual remainder is zero-extended to cbRemainder bytes.
cbRemainderA capacity of the remainder buffer in bytes, and a byte length of the resulting remainder which is computed modulo bcbRemainder. If cbRemainder is zero, then no remainder is returned by the function, in which case pRemainder can be equal to nullptr.
Returns
A POSIX error code which results from the operation. On success the function returns zero. If the divisor is zero, the function returns EDOM.

The function operates on Big-Endian integers represented by vectors addressed by pDividend and pDivisor. That is, if pDividend points to the vector \(V_X = \{x_0,\dots,x_{n_x}\}\), where nx = cbDividend - 1, pDivisor points to the vector \(V_Y = \{y_0,\dots,y_{n_y}\}\), where ny = cbDivisor - 1, then the associated dividend and divisor respectively are \(X = \sum_{i=0}^{n_x}x_{n_x-i}\cdot b^i\) and \(Y=\sum_{i=0}^{n_y}y_{n_y-i}\cdot b^i\).

Assuming that \(Q=\left\lfloor X/Y\right\rfloor\) and \(R=X \bmod Y\) are the exact quotient and remainder of the Euclidean division, \(Q = \sum_{i=0}^{n_Q}q_i\cdot b^i\), where \(n_Q = n_x - n_y\), and \(R = \sum_{i=0}^{n_y}r_i\cdot b^i\). In order to fit the quotient and the remainder to the buffers pointed to by pQuotient and pRemainder, the function either zero-extends them or contracts them leaving the number of lowest-order bytes which can fill the available space effectively resulting in \(Q' = Q\bmod b^{n_{Q'}} = \sum_{i=0}^{n_{Q'}} q'_i\cdot b^i\) and \(R'=R\bmod b^{n_{R'}} = \sum_{i=0}^{n_{R'}}r'_i\cdot b^i\), where nQ' = cbQuotient - 1, \(0\le i\le n_Q \Rightarrow q'_i = q_{n_Q-i}\) and \(q'_i = 0\) otherwise, nR' = cbRemainder - 1, \(0\le i\le n_R \Rightarrow r'_{n_R-i} = r_i\) and \(r'_i = 0\) otherwise. Then the vectors \(V_{Q'}=\{q'_0,\dots,q'_{n_{Q'}}\}\) and \(V_{R'}=\{r'_0,\dots,r'_{n_{R'}}\}\) are written to the buffers referenced by pQuotient and pRemainder respectively.

If cbQuotient is zero, then no quotient is produced by the function. Likewise, if cbRemainder is zero, no remainder is produced. If both cbQuotient and cbRemainder are zero, then the function performs no action except for checking whether the divisor \(Y = 0\) and returning the EDOM error if it is the case.

If cbResult is less than it is required to hold the complete remainder, the function needs to allocate internal memory buffers, which can lead to performance drop. From the performance perspective, the function performs the best way if cbResult is greater or equal to cbDivisor and is an integer multiply of a byte size of a word on the target machine.

None of the buffers specified by parameters may overlap.

To perform Euclidean division of Little-Endian integers use memdiv_LE.

See also
memdiv_LE;
memmul_BE;
memadd_BE;
memsub_BE;
memrsh_BE.