YoushouldhavereceivedcopiesoftheGNUGeneralPublicLicenseandthe GNULesserGeneralPublicLicensealongwiththeGNUMPLibrary.Ifnot,
see https://www.gnu.org/licenses/. */
#include"gmp-impl.h" #include"longlong.h"
/* Use the simple loop by default. The generic count_trailing_zeros is not veryfast,andtheextratrickeryofmethod3hasproventobelessuse
than might have been though. */ #ifndef JACOBI_BASE_METHOD #define JACOBI_BASE_METHOD 2 #endif
/* Use a simple loop. A disadvantage of this is that there's a branch on a
50/50 chance of a 0 or 1 low bit. */ #if JACOBI_BASE_METHOD == 2 #define PROCESS_TWOS_EVEN \
{ \ int two; \
two = JACOBI_TWO_U_BIT1 (b); \ do \
{ \
a >>= 1; \
result_bit1 ^= two; \
ASSERT (a != 0); \
} \ while ((a & 1) == 0); \
} #define PROCESS_TWOS_ANY \ if ((a & 1) == 0) \
PROCESS_TWOS_EVEN; #endif
/* Process one bit arithmetically, then a simple loop. This cuts the loop conditiondowntoa25/75chance,whichshouldbranchpredictbetter.
The CPU will need a reasonable variable left shift. */ #if JACOBI_BASE_METHOD == 3 #define PROCESS_TWOS_EVEN \
{ \ int two, mask, shift; \
\
two = JACOBI_TWO_U_BIT1 (b); \
mask = (~a & 2); \
a >>= 1; \
\
shift = (~a & 1); \
a >>= shift; \
result_bit1 ^= two ^ (two & mask); \
\ while ((a & 1) == 0) \
{ \
a >>= 1; \
result_bit1 ^= two; \
ASSERT (a != 0); \
} \
} #define PROCESS_TWOS_ANY \
{ \ int two, mask, shift; \
\
two = JACOBI_TWO_U_BIT1 (b); \
shift = (~a & 1); \
a >>= shift; \
\
mask = shift << 1; \
result_bit1 ^= (two & mask); \
\ while ((a & 1) == 0) \
{ \
a >>= 1; \
result_bit1 ^= two; \
ASSERT (a != 0); \
} \
} #endif
#if JACOBI_BASE_METHOD < 4 /* Calculate the value of the Jacobi symbol (a/b) of two mp_limb_t's, but witharestrictedrangeofinputsaccepted,namelyb>1,bodd.
DuplicatingtheloopbodytoavoidtheMP_LIMB_T_SWAP(a,b)wouldbe possible,butacoupleoftestssuggestit'snotasignificantspeedup,
and may even be a slowdown, so what's here is good enough for now. */
int
mpn_jacobi_base (mp_limb_t a, mp_limb_t b, int result_bit1)
{
ASSERT (b & 1); /* b odd */
ASSERT (b != 1);
#if JACOBI_BASE_METHOD == 4 /* Computes (a/b) for odd b > 1 and any a. The initial bit is taken as a *parameter.Wehavenoneedfortheconventionthatthesignisin
* bit 1, internally we use bit 0. */
/* FIXME: Could try table-based count_trailing_zeros. */ int
mpn_jacobi_base (mp_limb_t a, mp_limb_t b, int bit)
{ int c;
ASSERT (b & 1);
ASSERT (b > 1);
if (a == 0) /* This is the only line which depends on b > 1 */ return0;
bit >>= 1;
/* Below, we represent a and b shifted right so that the least
significant one bit is implicit. */
b >>= 1;
count_trailing_zeros (c, a);
bit ^= c & (b ^ (b >> 1));
/* We may have c==GMP_LIMB_BITS-1, so we can't use a>>c+1. */
a >>= c;
a >>= 1;
do
{
mp_limb_t t = a - b;
mp_limb_t bgta = LIMB_HIGHBIT_TO_MASK (t);
if (t == 0) return0;
/* If b > a, invoke reciprocity */
bit ^= (bgta & a & b);
/* b <-- min (a, b) */
b += (bgta & t);
/* a <-- |a - b| */
a = (t ^ bgta) - bgta;
/* Number of trailing zeros is the same no matter if we look at
* t or a, but using t gives more parallelism. */
count_trailing_zeros (c, t);
c ++; /* (2/b) = -1 if b = 3 or 5 mod 8 */
bit ^= c & (b ^ (b >> 1));
a >>= c;
} while (a > 0);
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.