Dealing with Fractional values

The question Convert a text fraction to a decimal arose and though I’d post a solution to it using a class with the implicit operator. Admittedly I didn’t do a lot of testing on this, but it should handle a great deal of situations as-is. If you need more flexibility, feel free to extend it yourself (and post your modification here so I can update any edge cases).

With that said, here’s the class:

public class FractionalNumber
  1. {
  2.     public Double Result
  3.     {
  4.         get { return this.result; }
  5.         private set { this.result = value; }
  6.     }
  7.     private Double result;
  8.  
  9.     public FractionalNumber(String input)
  10.     {
  11.         this.Result = this.Parse(input);
  12.     }
  13.  
  14.     private Double Parse(String input)
  15.     {
  16.         input = (input ?? String.Empty).Trim();
  17.         if (String.IsNullOrEmpty(input))
  18.         {
  19.             throw new ArgumentNullException("input");
  20.         }
  21.  
  22.         // standard decimal number (e.g. 1.125)
  23.         if (input.IndexOf('.') != -1 || (input.IndexOf(' ') == -1 && input.IndexOf('/') == -1 && input.IndexOf('\\') == -1))
  24.         {
  25.             Double result;
  26.             if (Double.TryParse(input, out result))
  27.             {
  28.                 return result;
  29.             }
  30.         }
  31.  
  32.         String[] parts = input.Split(new[] { ' ', '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
  33.  
  34.         // stand-off fractional (e.g. 7/8)
  35.         if (input.IndexOf(' ') == -1 && parts.Length == 2)
  36.         {
  37.             Double num, den;
  38.             if (Double.TryParse(parts[0], out num) && Double.TryParse(parts[1], out den))
  39.             {
  40.                 return num / den;
  41.             }
  42.         }
  43.  
  44.         // Number and fraction (e.g. 2 1/2)
  45.         if (parts.Length == 3)
  46.         {
  47.             Double whole, num, den;
  48.             if (Double.TryParse(parts[0], out whole) && Double.TryParse(parts[1], out num) && Double.TryParse(parts[2], out den))
  49.             {
  50.                 return whole + (num / den);
  51.             }
  52.         }
  53.  
  54.         // Bogus / unable to parse
  55.         return Double.NaN;
  56.     }
  57.  
  58.     public override string ToString()
  59.     {
  60.         return this.Result.ToString();
  61.     }
  62.  
  63.     public static implicit operator Double(FractionalNumber number)
  64.     {
  65.         return number.Result;
  66.     }
  67. }

Now your integration should resemble something like:

Double fractional = new FractionalNumber("3 1/2"); // = 3.5

Flattr this!