/* * mplogic.c * * Bitwise logical operations on MPI values * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*------------------------------------------------------------------------*/ /* mpl_not(a, b) - compute b = ~a mpl_and(a, b, c) - compute c = a & b mpl_or(a, b, c) - compute c = a | b mpl_xor(a, b, c) - compute c = a ^ b
*/
Count the number of set bits in the binary representation of a. Returns MP_OKAY and sets 'num' to be the number of such bits, if possible. If num is NULL, the result is thrown away, but it is not considered an error.
mpl_num_clear() does basically the same thing for clear bits.
*/
Determines the bitwise parity of the value given. Returns MP_EVEN if an even number of digits are set, MP_ODD if an odd number are set.
*/
/* {{{ mpl_parity(a) */
mp_err
mpl_parity(mp_int *a)
{ unsignedint ix; int par = 0;
mp_digit cur;
ARGCHK(a != NULL, MP_BADARG);
for (ix = 0; ix < USED(a); ix++) { int shft = (sizeof(mp_digit) * CHAR_BIT) / 2;
cur = DIGIT(a, ix);
/* Compute parity for current digit */ while (shft != 0) {
cur ^= (cur >> shft);
shft >>= 1;
}
cur &= 1;
/* XOR with running parity so far */
par ^= cur;
}
if (par) return MP_ODD; else return MP_EVEN;
} /* end mpl_parity() */
/* }}} */
/* mpl_set_bit
Returns MP_OKAY or some error code. Grows a if needed to set a bit to 1.
*/
mp_err
mpl_set_bit(mp_int *a, mp_size bitNum, mp_size value)
{
mp_size ix;
mp_err rv;
mp_digit mask;
ARGCHK(a != NULL, MP_BADARG);
ix = bitNum / MP_DIGIT_BIT; if (ix + 1 > MP_USED(a)) {
rv = s_mp_pad(a, ix + 1); if (rv != MP_OKAY) return rv;
}
/* mpl_get_bits - Extracts numBits bits from a, where the least significant extracted bit is bit lsbNum. Returns a negative value if error occurs. - Because sign bit is used to indicate error, maximum number of bits to be returned is the lesser of (a) the number of bits in an mp_digit, or (b) one less than the number of bits in an mp_err. - lsbNum + numbits can be greater than the number of significant bits in integer a, as long as bit lsbNum is in the high order digit of a.
*/
mp_err
mpl_get_bits(const mp_int *a, mp_size lsbNum, mp_size numBits)
{
mp_size rshift = (lsbNum % MP_DIGIT_BIT);
mp_size lsWndx = (lsbNum / MP_DIGIT_BIT);
mp_digit *digit = MP_DIGITS(a) + lsWndx;
mp_digit mask = ((1 << numBits) - 1);
#define LZCNTLOOP(i) \ do { \
x = d >> (i); \
mask = (0 - x); \
mask = (0 - (mask >> (MP_DIGIT_BIT - 1))); \
bits += (i)&mask; \
d ^= (x ^ d) & mask; \
} while (0)
/* mpl_significant_bits returns number of significant bits in abs(a). In other words: floor(lg(abs(a))) + 1. returns 1 if value is zero.
*/
mp_size
mpl_significant_bits(const mp_int *a)
{ /* start bits at 1. lg(0) = 0 => bits = 1 by function semantics. below does a binary search for the _position_ of the top bit set, which is floor(lg(abs(a))) for a != 0.
*/
mp_size bits = 1; int ix;
ARGCHK(a != NULL, MP_BADARG);
for (ix = MP_USED(a); ix > 0;) {
mp_digit d, x, mask; if ((d = MP_DIGIT(a, --ix)) == 0) continue; #if !defined(MP_USE_UINT_DIGIT)
LZCNTLOOP(32); #endif
LZCNTLOOP(16);
LZCNTLOOP(8);
LZCNTLOOP(4);
LZCNTLOOP(2);
LZCNTLOOP(1); break;
}
bits += ix * MP_DIGIT_BIT; return bits;
}
#undef LZCNTLOOP
/*------------------------------------------------------------------------*/ /* HERE THERE BE DRAGONS */
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-06)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.