Java Integer Mod modMultiply(long a, long b, int m)

Here you can find the source of modMultiply(long a, long b, int m)

Description

Modular multiplication.
Returns ( a * b )( mod m ).
Differs from ( a * b ) % m in that it always returns non-negative value and never overflows.
If m = 0, #NOT_FOUND is returned.

License

Open Source License

Parameter

Parameter Description
a first value
b second value
m a modulus

Return

( a * b )( mod m ), or if m = 0

Declaration

public static int modMultiply(long a, long b, int m) 

Method Source Code

//package com.java2s;
//License from project: Open Source License 

public class Main {
    /**//from   w ww .  j  ava 2s .  c  o m
     * Some methods return this value as indication that the answer doesn't exist or is undefined.<br>
     * For example, when mod = 0 in modular arithmetics, or when a number isn't a perfect power and
     * a function should return its base.
     * <p>This constant equals to {@code Integer.MIN_VALUE} because {@code Integer.MIN_VALUE}
     * can't be a base of any perfect power that fits in long. Proof:<ul>
     * <li>Base of perfect square is a positive number.</li>
     * <li>Integer.MIN_VALUE<sup>3</sup> = ((-2)<sup>31</sup>)<sup>3</sup> = (-2)<sup>93</sup> &lt; (-2)<sup>63</sup> = Long.MIN_VALUE.</li>
     * <li>Higher powers would give higher values.</li></ul>
     * So no power greater than one can return base = {@code Integer.MIN_VALUE} for any long integer.
     * <p>Also, any modular arithmetic operation returns non-negative value,
     * so negative values can be used as error codes.
     * <p>Error codes are more desirable than throwing an exception when performance matters.
     */
    public static final int NOT_FOUND = Integer.MIN_VALUE;

    /**
     * Modular multiplication.<br>
     * Returns ( a * b )( mod m ).<br>
     * Differs from ( a * b ) % m in that it always returns non-negative value and never overflows.<br>
     * If m = 0, {@link #NOT_FOUND} is returned.
     * @param a first value
     * @param b second value
     * @param m a modulus
     * @return ( a * b )( mod m ), or {@link #NOT_FOUND} if m = 0
     */
    public static int modMultiply(long a, long b, int m) {
        if (m <= 0) {
            if (m == 0)
                return NOT_FOUND;
            m = -m;
        }
        a %= m;
        b %= m;
        a = (a * b) % m;
        if (a < 0L)
            a += m;
        return (int) a;
    }

    /**
     * Modular multiplication.<br>
     * Returns ( a * b )( mod m ).<br>
     * Differs from ( a * b ) % m in that it always returns non-negative value and never overflows.<br>
     * If m = 0, {@link #NOT_FOUND} is returned.
     * @param a first value
     * @param b second value
     * @param m a modulus
     * @return ( a * b )( mod m ), or {@link #NOT_FOUND} if m = 0
     */
    public static long modMultiply(long a, long b, long m) {
        if (m <= 0L) {
            if (m == 0L)
                return NOT_FOUND;
            if (m == Long.MIN_VALUE) {
                a *= b;
                if (a < 0L)
                    a += m;
                return a;
            }
            m = -m;
        }
        a %= m;
        b %= m;
        if (m <= Integer.MAX_VALUE) {
            // Safe simple multiplication available.
            a = (a * b) % m;
            if (a < 0L)
                a += m;
            return a;
        }
        if (a < 0L)
            a += m;
        if (b < 0L)
            b += m;
        // a = min( a, b ), b = max( a, b )
        if (a > b) {
            long number = a;
            a = b;
            b = number;
        }
        // Corner cases of Schrage's method.
        if (a < 2L)
            return a * b;
        if (b == m - 1L)
            return m - a;
        // Safe simple multiplication available.
        if (Long.numberOfLeadingZeros(a) + Long.numberOfLeadingZeros(b) > 64)
            return (a * b) % m;
        // Schrage's method.
        // http://home.earthlink.net/~pfenerty/pi/schrages_method.html
        // http://objectmix.com/java/312426-extending-schrage-multiplication.html
        long quot = m / a;
        long rem = m - quot * a;
        if (rem < quot) {
            long number = b / quot;
            number = a * (b - quot * number) - rem * number;
            return number < 0L ? number + m : number;
        }
        // Bitwise multiplication.
        long leftTillOverflow;
        long number = 0L;
        while (a > 0L) {
            if ((a & 1L) == 1L) {
                leftTillOverflow = m - number;
                if (leftTillOverflow > b)
                    number += b;
                else
                    number = b - leftTillOverflow;
            }
            a >>= 1;
            leftTillOverflow = m - b;
            if (leftTillOverflow > b)
                b <<= 1;
            else
                b -= leftTillOverflow;
        }
        return number;
    }
}

Related

  1. modifyDummyString(String dummyString, int beginTag, int endTag)
  2. modifyPublicPortCheckRange(String modifiedVal, int dashCnt)
  3. modifyString(char firstCharacter, String srcString, int indexOfSubstring)
  4. modInverse(int a, int n)
  5. modInverse(int n, int mod)
  6. modPos(int divisor, int dividend)
  7. modSubtract(long a, long b, int m)
  8. modularExp(long base, long exp, int modulus)
  9. modularInverses(int p)