Created
June 1, 2014 15:22
-
-
Save andyhuey/80d8c3d392198bd511af to your computer and use it in GitHub Desktop.
fractions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Globalization; | |
namespace MySuit.MySuitV2.BLL | |
{ | |
public class Utility | |
{ | |
public static decimal FractionToDecimal(string frac) | |
{ | |
// this method should convert a fraction, e.g. "12 1/4" to a decimal, e.g. 12.25. | |
// based on http://amrelgarhytech.blogspot.com/2008/03/fraction-to-decimal.html | |
// TODO: not sure how best to handle exceptions here. (parse errors, div by zero, null/empty string input...) | |
decimal rv; | |
int numerator, denominator, wholePart = 0; | |
int sign = 1; | |
if (string.IsNullOrEmpty(frac)) | |
return 0m; | |
// deal with signs | |
frac = frac.Trim().TrimStart('+'); | |
if (frac[0] == '-') | |
{ | |
frac = frac.TrimStart('-'); | |
sign = -1; | |
} | |
frac = frac.Trim(); | |
if (frac.IndexOf("/") > 0) | |
{ | |
if (frac.IndexOf(" ") > 0) | |
{ | |
wholePart = int.Parse(frac.Substring(0, frac.IndexOf(" "))); | |
frac = frac.Substring(frac.IndexOf(" ")); | |
} | |
numerator = int.Parse(frac.Substring(0, frac.IndexOf("/"))); | |
denominator = int.Parse(frac.Substring(frac.IndexOf("/") + 1)); | |
rv = sign * (wholePart + ((decimal)numerator / denominator)); | |
} | |
else | |
{ | |
rv = decimal.Parse(frac); | |
} | |
return rv; | |
} | |
public static string DecimalToFractionSigned(decimal value) | |
{ | |
// always put a sign (+/-) in front | |
string rv = DecimalToFraction(value); | |
if (rv[0] != '-') | |
rv = string.Format("+{0}", rv); | |
return rv; | |
} | |
public static string DecimalToFraction(decimal value) | |
{ | |
// taken from here: http://bit.ly/tHaKrK and modified to work with negative numbers too. | |
int sign = 1; | |
if (value < 0) | |
{ | |
value = Math.Abs(value); | |
sign = -1; | |
} | |
// get the whole value of the fraction | |
decimal mWhole = Math.Truncate(value); | |
// get the fractional value | |
decimal mFraction = value - mWhole; | |
// initialize a numerator and denominator | |
uint mNumerator = 0; | |
uint mDenominator = 1; | |
// ensure that there is actually a fraction | |
if (mFraction > 0m) | |
{ | |
// convert the value to a string so that you can count the number of decimal places there are | |
string strFraction = mFraction.ToString().Remove(0, 2); | |
// store the number of decimal places | |
uint intFractLength = (uint)strFraction.Length; | |
// set the numerator to have the proper amount of zeros | |
mNumerator = (uint)Math.Pow(10, intFractLength); | |
// parse the fraction value to an integer that equals [fraction value] * 10^[number of decimal places] | |
uint.TryParse(strFraction, out mDenominator); | |
// get the greatest common divisor for both numbers | |
uint gcd = GreatestCommonDivisor(mDenominator, mNumerator); | |
// divide the numerator and the denominator by the greatest common divisor | |
mNumerator = mNumerator / gcd; | |
mDenominator = mDenominator / gcd; | |
} | |
// create a string builder | |
StringBuilder mBuilder = new StringBuilder(); | |
// add the whole number if it's greater than 0 | |
if (mWhole > 0m) | |
{ | |
mBuilder.Append(mWhole); | |
} | |
// add the fraction if it's greater than 0m | |
if (mFraction > 0m) | |
{ | |
if (mBuilder.Length > 0) | |
{ | |
mBuilder.Append(" "); | |
} | |
mBuilder.Append(mDenominator); | |
mBuilder.Append("/"); | |
mBuilder.Append(mNumerator); | |
} | |
if (sign == -1) | |
mBuilder.Insert(0, '-'); | |
return mBuilder.ToString(); | |
} | |
private static uint GreatestCommonDivisor(uint valA, uint valB) | |
{ | |
// return 0 if both values are 0 (no GSD) | |
if (valA == 0 && valB == 0) | |
{ | |
return 0; | |
} | |
// return value b if only a == 0 | |
else if (valA == 0 && valB != 0) | |
{ | |
return valB; | |
} | |
// return value a if only b == 0 | |
else if (valA != 0 && valB == 0) | |
{ | |
return valA; | |
} | |
// actually find the GSD | |
else | |
{ | |
uint first = valA; | |
uint second = valB; | |
while (first != second) | |
{ | |
if (first > second) | |
{ | |
first = first - second; | |
} | |
else | |
{ | |
second = second - first; | |
} | |
} | |
return first; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment