Java gcd gcdPositive(int... args)

Here you can find the source of gcdPositive(int... args)

Description

Returns the greatest common divisor of the given absolute values.

License

Apache License

Parameter

Parameter Description
args non-negative numbers

Return

the greatest common divisor.

Declaration

public static int gcdPositive(int... args) 

Method Source Code

//package com.java2s;
/*******************************************************************************
 * Copyright 2014 See AUTHORS file./* w w  w  .  java  2  s.  com*/
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

public class Main {
    /** Returns the greatest common divisor of two <em>positive</em> numbers (this precondition is <em>not</em> checked and the
     * result is undefined if not fulfilled) using the "binary gcd" method which avoids division and modulo operations. See Knuth
     * 4.5.2 algorithm B. The algorithm is due to Josef Stein (1961).
     * <p>
     * Special cases:
     * <ul>
     * <li>The result of {@code gcd(x, x)}, {@code gcd(0, x)} and {@code gcd(x, 0)} is the value of {@code x}.</li>
     * <li>The invocation {@code gcd(0, 0)} is the only one which returns {@code 0}.</li>
     * </ul>
     * 
     * @param a a non negative number.
     * @param b a non negative number.
     * @return the greatest common divisor. */
    public static int gcdPositive(int a, int b) {
        if (a == 0)
            return b;

        if (b == 0)
            return a;

        // Make "a" and "b" odd, keeping track of common power of 2.
        final int aTwos = Integer.numberOfTrailingZeros(a);
        a >>= aTwos;
        final int bTwos = Integer.numberOfTrailingZeros(b);
        b >>= bTwos;
        final int shift = aTwos <= bTwos ? aTwos : bTwos; // min(aTwos, bTwos);

        // "a" and "b" are positive.
        // If a > b then "gdc(a, b)" is equal to "gcd(a - b, b)".
        // If a < b then "gcd(a, b)" is equal to "gcd(b - a, a)".
        // Hence, in the successive iterations:
        // "a" becomes the absolute difference of the current values,
        // "b" becomes the minimum of the current values.
        while (a != b) {
            final int delta = a - b;
            b = a <= b ? a : b; // min(a, b);
            a = delta < 0 ? -delta : delta; // abs(delta);

            // Remove any power of 2 in "a" ("b" is guaranteed to be odd).
            a >>= Integer.numberOfTrailingZeros(a);
        }

        // Recover the common power of 2.
        return a << shift;
    }

    /** Returns the greatest common divisor of the given absolute values. This implementation uses {@link #gcdPositive(int, int)}
     * and has the same special cases.
     * 
     * @param args non-negative numbers
     * @return the greatest common divisor. */
    public static int gcdPositive(int... args) {
        if (args == null || args.length < 2)
            throw new IllegalArgumentException("gcdPositive requires at least two arguments");
        int result = args[0];
        int n = args.length;
        for (int i = 1; i < n; i++) {
            result = gcdPositive(result, args[i]);
        }
        return result;
    }
}

Related

  1. gcd(long[] array)
  2. gcd1(long given1, long given2)
  3. GCDHelper(long a, long b)
  4. gcdMultiple(int[] nums)
  5. gcdPositive(int a, int b)
  6. gcdRec(int a, int b)
  7. gcdUsingEuclides(long x, long y)
  8. gcdUsingRecursion(long a, long b)