Chibueze Opata Chibueze Opata - 1 year ago 131
C# Question

Algorithm for simplifying decimal to fractions

I tried writing an algorithm to simplify a decimal to a fraction and realized it wasn't too simple. Surprisingly I looked online and all the codes I found where either too long, or wouldn't work in some cases. What was even more annoying was that they didn't work for recurring decimals. I was wondering however whether there would be a mathematician/programmer here who understands all the involved processes in simplifying a decimal to a fraction. Anyone?

Answer Source

Well, seems I finally had to do it myself. I just had to create a program simulating the natural way I would solve it myself. I just submitted the code to codeproject as writing out the whole code here won't be suitable. You can download the project from here Fraction_Conversion, or look at the codeproject page here.

Here's how it works:

  1. Find out whether given decimal is negative
  2. Convert decimal to absolute value
  3. Get integer part of given decimal
  4. Get the decimal part
  5. Check whether decimal is recurring. If decimal is recurring, we then return the exact recurring decimal
  6. If decimal is not recurring, start reduction by changing numerator to 10^no. of decimal, else we subtract 1 from numerator
  7. Then reduce fraction

Code Preview:

    private static string dec2frac(double dbl)
        char neg = ' ';
        double dblDecimal = dbl;
        if (dblDecimal == (int) dblDecimal) return dblDecimal.ToString(); //return no if it's not a decimal
        if (dblDecimal < 0)
            dblDecimal = Math.Abs(dblDecimal);
            neg = '-';
        var whole = (int) Math.Truncate(dblDecimal);
        string decpart = dblDecimal.ToString().Replace(Math.Truncate(dblDecimal) + ".", "");
        double rN = Convert.ToDouble(decpart);
        double rD = Math.Pow(10, decpart.Length);

        string rd = recur(decpart);
        int rel = Convert.ToInt32(rd);
        if (rel != 0)
            rN = rel;
            rD = (int) Math.Pow(10, rd.Length) - 1;
        //just a few prime factors for testing purposes
        var primes = new[] {41, 43, 37, 31, 29, 23, 19, 17, 13, 11, 7, 5, 3, 2};
        foreach (int i in primes) reduceNo(i, ref rD, ref rN);

        rN = rN + (whole*rD);
        return string.Format("{0}{1}/{2}", neg, rN, rD);

Thanks @ Darius for given me an idea of how to solve the recurring decimals :)