public static Rational64 FromInt64Bits(Int64 bits)
        {
            var numerator   = unchecked ((UInt32)bits);
            var denominator = unchecked ((Int32)(bits >> 32));
            var s           = 0 > denominator;

            if (s)
            {
                denominator = -denominator;
            }
            else
            {
                ++denominator;
            }
            var d = EuclideanAlgorithm.GreatestCommonDivisorPartial(numerator, unchecked ((UInt32)denominator));

            if (s)
            {
                return(new Rational64(unchecked (((UInt64)((UInt32)(-denominator) / d) << 32) | numerator / d)));
            }
            else
            {
                return(new Rational64(unchecked (((UInt64)((UInt32)denominator / d - 1) << 32) | numerator / d)));
            }
        }
        public static UInt64 MultiplyAsRational128(Rational64 first, Rational64 second, out UInt64 bits_hi)
        {
            unchecked {
                var first_numerator    = (UInt32)first.bits;
                var first_denominator  = (Int32)(first.bits >> 32);
                var second_numerator   = (UInt32)second.bits;
                var second_denominator = (Int32)(second.bits >> 32);
                if (0 == first_numerator || 0 == second_numerator)
                {
                    bits_hi = 0;
                    return(0);
                }
                var s = 0 > (first_denominator ^ second_denominator);
                if (0 <= first_denominator)
                {
                    ++first_denominator;
                }
                else
                {
                    first_denominator = -first_denominator;
                }
                if (0 <= second_denominator)
                {
                    ++second_denominator;
                }
                else
                {
                    second_denominator = -second_denominator;
                }
                {
                    var d = EuclideanAlgorithm.GreatestCommonDivisorPartial((UInt32)first_denominator, second_numerator);
                    first_denominator = (Int32)((UInt32)first_denominator / d);
                    second_numerator /= d;
                }
                {
                    var d = EuclideanAlgorithm.GreatestCommonDivisorPartial(first_numerator, (UInt32)second_denominator);
                    first_numerator   /= d;
                    second_denominator = (Int32)((UInt32)second_denominator / d);
                }
                var p = (UInt64)first_numerator * second_numerator;
                var q = (Int64)((UInt64)(UInt32)first_denominator * (UInt32)second_denominator);

                if (s)
                {
                    q = -q;
                }
                else
                {
                    --q;
                }
                bits_hi = (UInt64)q;
                return(p);
            }
        }
 public static Rational64 FromFraction(UInt32 numerator, Int32 denominator)
 {
     Contract.EnsuresOnThrow <DivideByZeroException>(0 == Contract.OldValue(denominator));
     unchecked {
         Int32 q;
         if (denominator > 0)
         {
             q = denominator;
         }
         else if (0 > denominator)
         {
             q = -denominator;
         }
         else
         {
             (denominator / denominator).Ignore();
             throw null;
         }
         if (0 == numerator)
         {
             return(default(Rational64));
         }
         var d = EuclideanAlgorithm.GreatestCommonDivisorPartial(numerator, (UInt32)q);
         numerator /= d;
         q         /= (Int32)d;
         if (denominator > 0)
         {
             --q;
         }
         else
         {
             q = -q;
         }
         return(new Rational64((UInt64)q << 32 | numerator));
     }
 }
        public static Rational64 Multiply(Rational64 first, Rational64 second)
        {
            unchecked {
                var first_numerator    = (UInt32)first.bits;
                var first_denominator  = (Int32)(first.bits >> 32);
                var second_numerator   = (UInt32)second.bits;
                var second_denominator = (Int32)(second.bits >> 32);
                if (0 == first_numerator || 0 == second_numerator)
                {
                    return(Zero);
                }
                var s = 0 > (first_denominator ^ second_denominator);
                if (0 <= first_denominator)
                {
                    ++first_denominator;
                }
                else
                {
                    first_denominator = -first_denominator;
                }
                if (0 <= second_denominator)
                {
                    ++second_denominator;
                }
                else
                {
                    second_denominator = -second_denominator;
                }
                {
                    var d = EuclideanAlgorithm.GreatestCommonDivisorPartial((UInt32)first_denominator, second_numerator);
                    first_denominator = (Int32)((UInt32)first_denominator / d);
                    second_numerator /= d;
                }
                {
                    var d = EuclideanAlgorithm.GreatestCommonDivisorPartial(first_numerator, (UInt32)second_denominator);
                    first_numerator   /= d;
                    second_denominator = (Int32)((UInt32)second_denominator / d);
                }

                /*
                 * var q = (Int64)((UInt64)(UInt32)first_denominator * (UInt32)second_denominator);
                 * if (s) {
                 *  q = -q;
                 * } else {
                 *  --q;
                 * }
                 * checked((Int32)q).Ignore();
                 * return new Rational64(checked(first_numerator * second_numerator) | (UInt64)q << 32);
                 */
                var p = (UInt64)first_numerator * second_numerator;
                var q = (Int64)((UInt64)(UInt32)first_denominator * (UInt32)second_denominator);
                p = checked ((UInt32)p);
                checked (unchecked ((UInt32)Int32.MinValue) - unchecked ((UInt64)q)).Ignore();
                if (s)
                {
                    return(new Rational64((UInt64)(-q << 32) | p));
                }
                else
                {
                    return(new Rational64((UInt64)(--q << 32) | p));
                }
            }
        }