문제

주어진 이상한 long x,내가 찾는 long y 이러한 그들의 제품 모듈 2**64 (즉,사용하여 넘치는 정상적인 산술)동등한 것 1.을 명확하게 무슨 뜻인:이 될 수 있는 계산에 몇 천년 이 방법:

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

내가 알고 있는 것이 해결될 수 있을 사용하여 빠르게 확장된 유클리드 알고리즘,하지만 그것을 할 수있는 능력을 필요로 나타내는 모든 참여자(이르 2**64, 도 산술 부호 없는 것을 도울).용 BigInteger 확실히 도움이 될 것이지만 내가 궁금해 있는 경우에는 간단한 방법으로,아마도를 사용하는 확장 유클리드 알고리즘 구현에 대한 긍정적인 갈망하고.

도움이 되었습니까?

해결책

여기에는 방법 중 하나 그것을 하고 있다.이 사용하는 확장 유클리드 알고리즘을 찾는 역의 abs(x) 모듈 262, 고 끝에 그것은'연장'응답하는 역 modulo264 고 적용하는 기호로 변경 필요한 경우:

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");
}

나는 그것을 발견하고 쉽게 작업 262 263, 주로 피할 수 있기 때문에 문제가 부정 번호:263 로 Java long 은 부정적이다.

다른 팁

그 동안 나는 회수/재창조 아주 간단한 해결책:

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;
}

그것은 작동하기 때문에 두 가지의:

  • 에서 각 반복하는 경우 해당 비트의 product1,그것의 잘못,그리고 해결하는 유일한 방법은 변경하여 해당 비트의 y
  • no 트 y 영향이 덜 중요한 비트의 product, 다,그래서 이전 작업 취소

로 시작했는데 int 이후 long 그것은 일해야 한도,그리고 대 int 나는 실행할 수 있는 완전한 테스트입니다.

또 다른 아이디어:이 있어야 합니다 숫자 n>0x**n == 1, 며,따라서 y == x**(n-1).이는 아마도 더 빠르고,나는 그냥 기억이 없어요 충분한 수학 계산 n.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top