Java reverse module 2 ** 64

Given the odd one long x, I search long yso that their product modulo 2**64(i.e. using ordinary overflow arithmetic) is 1. To understand what I mean: it could be calculated over several thousand years as follows:

for (long y=1; ; y+=2) {
    if (x*y == 1) return y;
}

I know that this can be quickly solved using the advanced Euclidean algorithm, but this requires the ability to represent all the numbers involved (before 2**64, so even unsigned arithmetic would not help). Using it for BigIntegersure will help, but I'm wondering if there is a simpler way, perhaps using the advanced Euclidean algorithm implemented for positive lengths.

+5
source share
2

. , abs(x) 2 62 "" 2 64 :

public static long longInverse(long x) {

    if (x % 2 == 0) { throw new RuntimeException("must be odd"); }

    long power = 1L << 62;

    long a = Math.abs(x);
    long b = power;
    long sign = (x < 0) ? -1 : 1;

    long c1 = 1;
    long d1 = 0;
    long c2 = 0;
    long d2 = 1;

    // Loop invariants:
    // c1 * abs(x) + d1 * 2^62 = a
    // c2 * abs(x) + d2 * 2^62 = b 

    while (b > 0) {
        long q = a / b;
        long r = a % b;
        // r = a - qb.

        long c3 = c1 - q*c2;
        long d3 = d1 - q*d2;

        // Now c3 * abs(x) + d3 * 2^62 = r, with 0 <= r < b.

        c1 = c2;
        d1 = d2;
        c2 = c3;
        d2 = d3;
        a = b;
        b = r;
    }

    if (a != 1) { throw new RuntimeException("gcd not 1 !"); }

    // Extend from modulo 2^62 to modulo 2^64, and incorporate sign change
    // if necessary.
    for (int i = 0; i < 4; ++i) {
        long possinv = sign * (c1 + (i * power));
        if (possinv * x == 1L) { return possinv; }
    }

    throw new RuntimeException("failed");
}

2 62 2 63 , : 2 63 Java long .

+1

/ :

public static int inverseOf(int x) {
    Preconditions.checkArgument((x&1)!=0, "Only odd numbers have an inverse, got " + x);
    int y = 1;
    for (int mask=2; mask!=0; mask<<=1) {
        final int product = x * y;
        final int delta = product & mask;
        y |= delta;
    }
    return y;
}

- :

  • , product 1, , - y
  • y product,

int, long , int .

: n>0 , x**n == 1 , , y == x**(n-1). , , n.

+1

All Articles