|
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.
[in] | pDividend | A pointer to an unsigned dividend. |
cbDividend | A byte size of the dividend pointed to by pDividend . | |
[in] | pDivisor | A pointer to an unsigned divisor. |
cbDivisor | Size of the divisor in bytes. | |
[out] | pQuotient | An 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. |
cbQuotient | A 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] | pRemainder | An 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. |
cbRemainder | A 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 . |
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.