Объясните, как работает взаимная проверка

Каждый раз я использую метод Евклида для проверки, если два числа взаимно просты. Но есть одно решение, которое использовало этот код для проверки совместимости, и время, затрачиваемое на это, было намного быстрее, чем метод Евклида: ( источник)

private static boolean isCoprime(long u, long v) {
    if (((u | v) & 1) == 0)
        return false;

    while ((u & 1) == 0)
        u >>= 1;
    if (u == 1)
        return true;

    do {
        while ((v & 1) == 0)
            v >>= 1;
        if (v == 1)
            return true;

        if (u > v) {
            long t = v;
            v = u;
            u = t;
        }
        v -= u;
    } while (v != 0);

    return false;
}

Я не могу понять, как это работает. (Я понимаю побитовые операции.) Например, что означают эти строки...

if (((u | v) & 1) == 0)
    return false;

Почему просто вернуть ложь? Также есть другие строки, которые я не могу понять, что происходит. Если кто-нибудь из вас мог бы просто дать мне немного прохождения, это очень поможет.

1 ответ

Решение

Размещенный вами код является модификацией двоичного алгоритма GCD. Вот мой аннотированный комментарий:

private static boolean isCoprime(long u, long v) {
    // If both numbers are even, then they are not coprime.
    if (((u | v) & 1) == 0) return false;

    // Now at least one number is odd. Eliminate all the factors of 2 from u.
    while ((u & 1) == 0) u >>= 1;

    // One is coprime with everything else by definition.
    if (u == 1) return true;

    do {
        // Eliminate all the factors of 2 from v, because we know that u and v do not have any 2's in common.
        while ((v & 1) == 0) v >>= 1;

        // One is coprime with everything else by definition.
        if (v == 1) return true;

        // Swap if necessary to ensure that v >= u.
        if (u > v) {
            long t = v;
            v = u;
            u = t;
        }

        // We know that GCD(u, v) = GCD(u, v - u).
        v -= u;
    } while (v != 0);

    // When we reach here, we have v = 0 and GCD(u, v) = current value of u, which is greater than 1.
    return false;
}
Другие вопросы по тегам