chsvlib
chsv helper source code

◆ memandnot_BE()

void Chusov::Memory::memandnot_BE ( void *  pDest,
std::size_t  cbDest,
const void *  pSrc1,
std::size_t  cbSrc1,
const void *  pSrc2,
std::size_t  cbSrc2 
)
noexcept

A generic form of bitwise NOT-AND of an arbitrary precision integer with another integer both of which are specified with byte vectors in the Big-Endian order.

Parameters
[out]pDestA pointer to an output buffer which receives the result of the computation. The buffer may overlap with pSrc1 and/or pSrc2.
cbDestThe capacity of the buffer pDest, in bytes, and a byte size of the resulting integer which is computed modulo bcbDest, where b = 2CHAR_BIT is a number of values that can be represented using one byte.
[in]pSrc1The first operand which is bitwise complemented and then combined with the second operand using bitwise AND in order to produce the final result.
cbSrc1The byte size of the first integer, that is the amount of data, in bytes, in the buffer pSrc1.
[in]pSrc2The second operand which is combined using bitwise AND with a bitwise complement of the integer pointed to by pSrc1.
cbSrc2The byte size of the second integer, that is the amount of data, in bytes, in the buffer pSrc2.

The function firstly zero-extends both of the integers so that the resulting integers will be of byte size equal to the maximum of cbSrc1, cbSrc2 and cbDest. Then the function computes bitwise AND of one's-complemented value of the first zero-extended arbitrary-precision integer with the zero-extended value of the second arbitrary-precision integer and then writes the result modulo two to the power of the bit size of the output buffer, i.e. truncates the result as necessary to fit the capacity of the output buffer. Both input integers and their buffers, pSrc1 and pSrc2, may have different byte sizes and may overlap with each other and with the destination buffer pDest. That is, there are no restrictions on respective sizes or respective positions of the three buffers in memory.

Let \(n_1 = \textrm{cbSrc1}\), \(n_2 = \textrm{cbSrc2}\), \(m = \textrm{cbDest}\), \(n = \min\left(n_1, n_2\right)\) and \(N = \max (n_1, n_2, m)\). Let also \(x\) be the value specified by the first buffer pSrc1, i.e. \(x=\sum_{i=0}^{n_1 - 1}x_i\cdot b^i = \sum_{i=0}^{n_1 - 1}x_i\cdot b^i + \sum_{i=n_1}^{N - 1}0\cdot b^i = \sum_{i=0}^{N - 1}x'_i\cdot b^i\), and \(y\) be the value specified by the second buffer pSrc2, i.e. \(y=\sum_{i=0}^{n_2 - 1}y_i\cdot b^i = \sum_{i=0}^{n_2 - 1}y_i\cdot b^i + \sum_{i=n_2}^{N - 1}0\cdot b^i = \sum_{i=0}^{N - 1}y'_i\cdot b^i\), where \(x'_i = x_i\), if \(0\le i < n_1\), and \(x'_i = 0\) otherwise; \(y'_i = y_i\), if \(0\le i < n_2\), and \(y'_i = 0\) otherwise. Then the function produces the result \(R = \left(\sum_{i=0}^{N - 1}(\bar{x'_i}\otimes y'_i)\cdot b^i\right)\bmod b^m = \left(\sum_{i=0}^{n-1}(\bar{x_i}\otimes y_i)\cdot b^i + \sum_{i=n}^{n_2 - 1}y_i\cdot b^i\right)\bmod b^m\), where \(\otimes\) denotes bitwise AND of two bytes, and \(\bar{x}\) is one's complement of \(x\), i.e. bitwise NOT.

That is, only the minimum of cbSrc1 and cbSrc2 lowest bytes of pSrc1 will be combined using NOT-AND with the respective bytes of pSrc2. Then, if cbSrc1 is greater than cbSrc2, then cbSrc1 - cbSrc2 bytes of the result will be zeroed out; otherwise, if cbSrc1 is less than cbSrc2, then cbSrc2 - cbSrc1 bytes of the result will be copied from the respective bytes of pSrc2. The final result will be composed of the lowest bytes of that to fit the cbDest capacity in bytes. That is, if cbDest is less than cbSrc2, then cbSrc2 - cbDest bytes of NOT-AND will be discarded. Otherwise, if cbDest is greater than cbSrc2, the cbDest - cbSrc2 highest bytes of the final result will be zeroed out (because \(\forall i \geq n_2 \Rightarrow \bar{x'_i}\otimes y'_i = \bar{x'_i}\otimes 0 = 0\)).

The function considers the specified parameters be in the Big-Endian format. That is, using the notation above, the first byte of pSrc1 specifies \(x_{n_1 - 1}\), and the last one specifies \(x_0\). Likewise, the first byte of pSrc2 specifies the value of \(y_{n_2 - 1}\), and the last one specifies \(y_0\). The result is also written in the Big-Endian format, therefore the last byte of the destination buffer receives the value of \(\bar{x'_0}\otimes y'_0\), the penultimate byte receives \(\bar{x'_1}\otimes y'_1\) and so on.

To calculate NOT-AND of values in the Little-Endian order, use the memandnot_LE function.

Compared to memandnot_copy and memandnot_inplace, the function also performs necessary calculations to match the process with the possibly overlapping buffers and differing sizes. If the operation of the function is known to be conducted with non-overlapping buffers of equal sizes, the preferable faster function for that is memandnot_copy. If the operation is done in place with otherwise non-overlapping buffers, the faster alternative is memandnot_inplace.

See also
memandnot_LE;
memandnot_copy;
memandnot_inplace;
memand_LE, memand_BE;
memor_LE, memor_BE;
memxor_LE, memxor_BE;
memornot_LE, memornot_BE;
memxornot_LE, memxornot_BE;
memnot_LE, memnot_BE.