Skip to content

Instantly share code, notes, and snippets.

@andyhuey
Created June 1, 2014 15:22
Show Gist options
  • Save andyhuey/80d8c3d392198bd511af to your computer and use it in GitHub Desktop.
Save andyhuey/80d8c3d392198bd511af to your computer and use it in GitHub Desktop.
fractions
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