コード例 #1
0
        /// <summary>Computes the nearest number greater than or equal to the
        /// specified start value that is coprime to another specified value.
        /// Returns 0 if no coprime was found in the range start to MaxValue.</summary>
        /// <param name="start">The start value.</param>
        /// <param name="value2">The value to test against.</param>
        /// <returns>The largest value that is less than or equal to the start value
        /// and also coprime to the other specified value.</returns>
        public static long NearestCoprimeCeiling(this long start, long value2)
        {
            ulong v1, v2;

            v2 = (value2 >= 0) ? (ulong)value2 : value2.AbsU();
            if ((value2 == 0) && (start <= -1))
            {
                return(-1);
            }
            if ((start == int.MaxValue) || ((value2 == 0) && (start > 1)))
            {
                return(0);
            }
            v1 = start.AbsU();
            if (start >= 0)
            {
                while (!IsCoprime(v1, v2))
                {
                    if (v1 == long.MaxValue)
                    {
                        return(0);
                    }
                    v1++;
                }
                return((long)v1);
            }
            else
            {
                while (!IsCoprime(v1, v2))
                {
                    v1--;
                }
                return(-(long)v1);
            }
        }
コード例 #2
0
 /// <summary>Computes the greatest common divisor of two values.</summary>
 /// <param name="value1">The first value.</param>
 /// <param name="value2">The other value.</param>
 /// <returns>The greatest common divisor of the two values.</returns>
 public static long Gcd(this long value1, long value2)
 {
     if ((value1 | value2) < 0)
     {
         return((long)Gcd(value1.AbsU(), value2.AbsU()));
     }
     return((long)Gcd((ulong)value1, (ulong)value2));
 }
コード例 #3
0
 /// <summary>Compute the modulo (division remainder) of a number multiplied by another number.</summary>
 /// <remarks>Overflow safe for all input values. </remarks>
 /// <param name="value1">The number to be multiplied by value2.</param>
 /// <param name="value2">The number to be multiplied by value1.</param>
 /// <param name="modulus">The number by which to divide value raised to the exponent power.</param>
 /// <returns>The remainder after dividing the product of multiplying value1 and value2.</returns>
 public static long MulMod(this long value1, long value2, long modulus)
 {
     if (modulus <= 0)
     {
         return(0);
     }
     unchecked {
         if ((value1 | value2) >= 0)
         {
             return((long)MulMod((ulong)value1, (ulong)value2, (ulong)modulus));
         }
         return(((1 | (value1 ^ value2) >> 63)) * (long)MulMod(value1.AbsU(), value2.AbsU(), (ulong)modulus));
     }
 }
コード例 #4
0
        /// <summary>Computes the nearest number less than or equal to the
        /// specified start value that is coprime to another specified value.
        /// Returns 0 if no coprime was found in the range MinValue to start.</summary>
        /// <param name="start">The start value.</param>
        /// <param name="value2">The value to test against.</param>
        /// <returns>The largest value that is less than or equal to the start value
        /// and also coprime to the other specified value.</returns>
        public static long NearestCoprimeFloor(this long start, long value2)
        {
            ulong v1, v2;

            v2 = (value2 >= 0) ? (ulong)value2 : value2.AbsU();
            if (start > 0)
            {
                return((long)NearestCoprimeFloor((ulong)start, v2));
            }
            if ((v2 == 0) && (start < -1))
            {
                return(0);
            }
            for (v1 = start.AbsU(); v1 <= (ulong)(-(long.MinValue + 1)) + 1; v1++)
            {
                if (v1.IsCoprime(v2))
                {
                    return(-(long)v1);
                }
            }
            return(0);
        }