using System; namespace Cryville.Common.Math { /// /// Provides a set of methods related to fractions. /// public static class FractionUtils { /// /// Converts a decimal to a fraction. /// /// The decimal. /// The error. /// The numerator. /// The denominator. /// is less than 0 or is not greater than 0 or not less than 1. public static void ToFraction(double value, double error, out int n, out int d) { if (value < 0.0) throw new ArgumentOutOfRangeException("value", "Must be >= 0."); if (error <= 0.0 || error >= 1.0) throw new ArgumentOutOfRangeException("accuracy", "Must be > 0 and < 1."); int num = (int)System.Math.Floor(value); value -= num; if (value < error) { n = num; d = 1; return; } if (1 - error < value) { n = num + 1; d = 1; return; } int lower_n = 0; int lower_d = 1; int upper_n = 1; int upper_d = 1; while (true) { int middle_n = lower_n + upper_n; int middle_d = lower_d + upper_d; if (middle_d * (value + error) < middle_n) { upper_n = middle_n; upper_d = middle_d; } else if (middle_n < (value - error) * middle_d) { lower_n = middle_n; lower_d = middle_d; } else { n = num * middle_d + middle_n; d = middle_d; return; } } } } }