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