using System;
public class Test
{
public static void Main()
{
foreach (var test in new[]{ "1", "1.5", "2.125", "3 7/8", "5/16" })
{
Console.WriteLine("{0,-5} = {1:0.000}", test, new FractionalNumber(test));
}
}
}
public class FractionalNumber
{
public Double Result
{
get { return this.result; }
private set { this.result = value; }
}
private Double result;
public FractionalNumber(String input)
{
this.Result = this.Parse(input);
}
private Double Parse(String input)
{
input = (input ?? String.Empty).Trim();
if (String.IsNullOrEmpty(input))
{
throw new ArgumentNullException("input");
}
// standard decimal number (e.g. 1.125)
if (input.IndexOf('.') != -1 || (input.IndexOf(' ') == -1 && input.IndexOf('/') == -1 && input.IndexOf('\\') == -1))
{
Double result;
if (Double.TryParse(input, out result))
{
return result;
}
}
String[] parts = input.Split(new[] { ' ', '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
// stand-off fractional (e.g. 7/8)
if (input.IndexOf(' ') == -1 && parts.Length == 2)
{
Double num, den;
if (Double.TryParse(parts[0], out num) && Double.TryParse(parts[1], out den))
{
return num / den;
}
}
// Number and fraction (e.g. 2 1/2)
if (parts.Length == 3)
{
Double whole, num, den;
if (Double.TryParse(parts[0], out whole) && Double.TryParse(parts[1], out num) && Double.TryParse(parts[2], out den))
{
return whole + (num / den);
}
}
// Bogus / unable to parse
return Double.NaN;
}
public override string ToString()
{
return this.Result.ToString();
}
public static implicit operator Double(FractionalNumber number)
{
return number.Result;
}
}
dXNpbmcgU3lzdGVtOwoKcHVibGljIGNsYXNzIFRlc3QKewoJcHVibGljIHN0YXRpYyB2b2lkIE1haW4oKQoJewoJCWZvcmVhY2ggKHZhciB0ZXN0IGluIG5ld1tdeyAiMSIsICIxLjUiLCAiMi4xMjUiLCAiMyA3LzgiLCAiNS8xNiIgfSkKICAgICAgICB7CiAgICAgICAgICAgIENvbnNvbGUuV3JpdGVMaW5lKCJ7MCwtNX0gPSB7MTowLjAwMH0iLCB0ZXN0LCBuZXcgRnJhY3Rpb25hbE51bWJlcih0ZXN0KSk7CiAgICAgICAgfQoJfQp9CgogICAgcHVibGljIGNsYXNzIEZyYWN0aW9uYWxOdW1iZXIKICAgIHsKICAgICAgICBwdWJsaWMgRG91YmxlIFJlc3VsdAogICAgICAgIHsKICAgICAgICAgICAgZ2V0IHsgcmV0dXJuIHRoaXMucmVzdWx0OyB9CiAgICAgICAgICAgIHByaXZhdGUgc2V0IHsgdGhpcy5yZXN1bHQgPSB2YWx1ZTsgfQogICAgICAgIH0KICAgICAgICBwcml2YXRlIERvdWJsZSByZXN1bHQ7CgogICAgICAgIHB1YmxpYyBGcmFjdGlvbmFsTnVtYmVyKFN0cmluZyBpbnB1dCkKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMuUmVzdWx0ID0gdGhpcy5QYXJzZShpbnB1dCk7CiAgICAgICAgfQoKICAgICAgICBwcml2YXRlIERvdWJsZSBQYXJzZShTdHJpbmcgaW5wdXQpCiAgICAgICAgewogICAgICAgICAgICBpbnB1dCA9IChpbnB1dCA/PyBTdHJpbmcuRW1wdHkpLlRyaW0oKTsKICAgICAgICAgICAgaWYgKFN0cmluZy5Jc051bGxPckVtcHR5KGlucHV0KSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEFyZ3VtZW50TnVsbEV4Y2VwdGlvbigiaW5wdXQiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gc3RhbmRhcmQgZGVjaW1hbCBudW1iZXIgKGUuZy4gMS4xMjUpCiAgICAgICAgICAgIGlmIChpbnB1dC5JbmRleE9mKCcuJykgIT0gLTEgfHwgKGlucHV0LkluZGV4T2YoJyAnKSA9PSAtMSAmJiBpbnB1dC5JbmRleE9mKCcvJykgPT0gLTEgJiYgaW5wdXQuSW5kZXhPZignXFwnKSA9PSAtMSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERvdWJsZSByZXN1bHQ7CiAgICAgICAgICAgICAgICBpZiAoRG91YmxlLlRyeVBhcnNlKGlucHV0LCBvdXQgcmVzdWx0KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBTdHJpbmdbXSBwYXJ0cyA9IGlucHV0LlNwbGl0KG5ld1tdIHsgJyAnLCAnLycsICdcXCcgfSwgU3RyaW5nU3BsaXRPcHRpb25zLlJlbW92ZUVtcHR5RW50cmllcyk7CgogICAgICAgICAgICAvLyBzdGFuZC1vZmYgZnJhY3Rpb25hbCAoZS5nLiA3LzgpCiAgICAgICAgICAgIGlmIChpbnB1dC5JbmRleE9mKCcgJykgPT0gLTEgJiYgcGFydHMuTGVuZ3RoID09IDIpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIERvdWJsZSBudW0sIGRlbjsKICAgICAgICAgICAgICAgIGlmIChEb3VibGUuVHJ5UGFyc2UocGFydHNbMF0sIG91dCBudW0pICYmIERvdWJsZS5UcnlQYXJzZShwYXJ0c1sxXSwgb3V0IGRlbikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bSAvIGRlbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gTnVtYmVyIGFuZCBmcmFjdGlvbiAoZS5nLiAyIDEvMikKICAgICAgICAgICAgaWYgKHBhcnRzLkxlbmd0aCA9PSAzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBEb3VibGUgd2hvbGUsIG51bSwgZGVuOwogICAgICAgICAgICAgICAgaWYgKERvdWJsZS5UcnlQYXJzZShwYXJ0c1swXSwgb3V0IHdob2xlKSAmJiBEb3VibGUuVHJ5UGFyc2UocGFydHNbMV0sIG91dCBudW0pICYmIERvdWJsZS5UcnlQYXJzZShwYXJ0c1syXSwgb3V0IGRlbikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdob2xlICsgKG51bSAvIGRlbik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEJvZ3VzIC8gdW5hYmxlIHRvIHBhcnNlCiAgICAgICAgICAgIHJldHVybiBEb3VibGUuTmFOOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIG92ZXJyaWRlIHN0cmluZyBUb1N0cmluZygpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gdGhpcy5SZXN1bHQuVG9TdHJpbmcoKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBzdGF0aWMgaW1wbGljaXQgb3BlcmF0b3IgRG91YmxlKEZyYWN0aW9uYWxOdW1iZXIgbnVtYmVyKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIG51bWJlci5SZXN1bHQ7CiAgICAgICAgfQogICAgfQ==