|
noexcept |
A generic form of bitwise NOT-OR of an arbitrary precision integer with another integer both of which are specified with byte vectors in the Little-Endian order.
[out] | pDest | A pointer to an output buffer which receives the result of the computation. The buffer may overlap with pSrc1 and/or pSrc2 . |
cbDest | The 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] | pSrc1 | The first operand which is bitwise complemented and then combined with the second operand using bitwise OR in order to produce the final result. |
cbSrc1 | The byte size of the first integer, that is the amount of data, in bytes, in the buffer pSrc1 . | |
[in] | pSrc2 | The second operand which is combined using bitwise OR with a bitwise complement of the integer pointed to by pSrc1 . |
cbSrc2 | The 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 size equal to the maximum of cbSrc1
, cbSrc2
and cbDest
. Then the function computes bitwise OR 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, m\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}⊞ y'_i)\cdot b^i\right)\bmod b^m = \left(\sum_{i=0}^{n-1}(\bar{x_i}⊞ y_i)\cdot b^i + \sum_{i=n}^{n_1 - 1}\bar{x_i}\cdot b^i + \sum_{i=n}^{n_2 - 1}(\bar{0}⊞y_i)\cdot b^i\right)\bmod b^m = \sum_{i=0}^{n-1}(\bar{x_i}⊞ y_i)\cdot b^i + \sum_{i=n}^{\min(n_1, m) - 1}\bar{x_i}\cdot b^i + \sum_{i=n}^{\min(n_2, m) - 1}\bar{0}\cdot b^i\), where \(⊞\) denotes bitwise OR of two bytes, and \(\bar{x}\) is one's complement of \(x\), i.e. bitwise NOT.
That is, the result of the NOT-OR operation before having been fit to the output buffer, is constructed as follows. First, the lowest \(n\) bytes result from actual NOT-OR of the respective bytes in pSrc1
and pSrc2
. Second, if cbSrc1
is less than cbSrc2
, then the bits of the remaining cbSrc2 - cbSrc1
high-order bytes are all set (because \(\forall i \geq n_1 \land \forall y'_i \Rightarrow \bar{x'_i}⊞ y'_i = \bar{0}⊞ y'_i = \bar{0}\)); otherwise, if cbSrc1
is greater than cbSrc2
, then cbSrc1 - cbSrc2
high-order bytes are set to one's complement (bitwise NOT) of respective bits in zero-extended pSrc1
(because \(\forall i\geq n_2 \land \forall x'_i \Rightarrow \bar{x'_i}⊞ y'_i = \bar{x'_i}⊞ 0 = \bar{x'_i}\)).
Finally, the result is fit into the destination buffer pDest
such that if cbSrc1
is less than cbDest
, then all bits of cbDest - cbSrc1
high-order bytes in the destination buffer are set to one; otherwise, if cbSrc1
is greater then all bits of cbDest
, then cbSrc1 - cbDest
high-order bytes of the result are discarded.
The function considers the specified parameters be in the Little-Endian format. That is, using the notation above, the first byte of pSrc1
specifies \(x_0\), and the last one specifies \(x_{n_1 - 1}\). Likewise, the first byte of pSrc2
specifies the value of \(y_0\), and the last one specifies \(y_{n_2 - 1}\). The result is also written in the Little-Endian format, therefore the first byte of the destination buffer receives the value of \(\bar{x'_0}⊞ y'_0\), the second byte receives \(\bar{x'_1}⊞ y'_1\) and so on.
To calculate NOT-OR of values in the Big-Endian order, use the memornot_BE function.
Compared to memornot_copy and memornot_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 memornot_copy. If the operation is done in place with otherwise non-overlapping buffers, the faster alternative is memornot_inplace.