I'm a first year computer science student. The programming paper I'm doing at Massey University is (unfortunately) in C#. And that s the language I'll use in the following examples.From what I've understood about basic data types; an integer is a whole number, with no fraction or decimal value, and doubles and floats are numbers with a decimal value. This works well for most common calculations, but sometimes it is more accurate or convenient to store a value as a fraction; a quotient of two integers. There seems to be no data type like this in C#. Am I missing something? Looking in the wrong place perhaps? I started writing a C# struct for it. This needs a lot of revision and testing. I remember feeling very tired when I last stopped working on it and not even bothering to write todos, even though I had issues and use cases in mind. My testing has been very limited. I have no use for this for now so will probably not work on it for a long time, if ever again. Please let me know if it was useful for you:
/// <summary>
/// A quotient of two integers. Commonly referred to as a fraction or rational number.
/// Strings formats contain one '/' character between two integers, e.g "2/3".
/// Throws InvalidFractionException if the constructor is called with a badly formatted string.
/// Throws ZeroDenominatorException if denominator is set to zero.
/// </summary>
public struct Quotient
{
int numerator;
int denominator;
/// <summary>
/// Set a quotient by passing integer values for numerator and denominator.
/// </summary>
/// <param name="Numerator">Numerator</param>
/// <param name="Denominator">Denominator</param>
public Quotient(int Numerator, int Denominator)
{
numerator = Numerator;
denominator = Denominator;
checkDenominator();
}
/// <summary>
/// Set a quotient by passing a string containing the '/' character. e.g. "3/4".
/// Also accepts integers in string format without the '/' character, by setting the denominator to 1. e.g. "5" sets numerator = 5 and denominator = 1.
/// </summary>
/// <param name="Fraction">A rational number as a fraction in string format</param>
public Quotient(string Fraction)
{
// Split the parameter into smaller parts
char[] separator = { '/' };
string[] parts = Fraction.Split(separator);
// We can only handle this if there are either one or two parts
if (parts.Length == 2 || parts.Length == 1)
// Fall through to default exception if part is not integer
numerator = Convert.ToInt32(parts[0].Trim());
else
throw new InvalidFractionException(Fraction);
// If a denominator was specified, set it. Else set denominator to 1.
if (parts.Length == 2)
denominator = Convert.ToInt32(parts[1].Trim());
else
denominator = 1;
checkDenominator();
}
public override string ToString()
{
return numerator + "/" + denominator;
}
/// <summary>
/// Convert the Quotient to a float
/// </summary>
/// <returns>The numeric value as a float</returns>
public float ToFloat()
{
// Convert each to a float before performing division.
return (float)numerator / (float)denominator;
}
/// <summary>
/// Round the Quotient to the nearest integer
/// </summary>
/// <returns>Rounded value as Integer</returns>
public int ToInt32()
{
// Add 0.5 for rounding
return (int)(this.ToFloat() + 0.5);
}
/// <summary>
/// Convert the Quotient to a double
/// </summary>
/// <returns>The numeric value as a double</returns>
public double ToDouble()
{
// Convert each to a doubler before performing division.
return (double)numerator / (double)denominator;
}
/// <summary>
/// The numerator of the Quotient
/// </summary>
public int Numerator
{
get
{
return numerator;
}
set
{
numerator = value;
}
}
/// <summary>
/// The Denominator of the Quotient
/// </summary>
public int Denominator
{
get
{
return denominator;
}
set
{
denominator = value;
checkDenominator();
}
}
/// <summary>
/// Checks that the denominator is a valid value (not zero). Throws ZeroDenominatorException if denominator is zero.
/// </summary>
/// <returns></returns>
private bool checkDenominator()
{
if (denominator == 0)
throw new ZeroDenominatorException(numerator);
return true;
}
}
/// <summary>
/// The value passed into Quotient.Quotient(string Fraction) is invalid.
/// </summary>
public class InvalidFractionException : Exception
{
string fraction;
/// <summary>
/// Constructor for InvalidFractionException
/// </summary>
/// <param name="Fraction">The string that should represent a fraction.</param>
public InvalidFractionException(string Fraction)
{
fraction = Fraction;
}
/// <summary>
/// The string that should represent a fraction but does not.
/// </summary>
public string Fraction
{
get
{
return fraction;
}
}
}
/// <summary>
/// The value of the denominator of a Quotient must not be zero.
/// </summary>
public class ZeroDenominatorException : Exception {
int numerator;
/// <summary>
/// constructor for ZeroDenominatorException
/// </summary>
/// <param name="Numerator">The numerator of the quotient</param>
public ZeroDenominatorException(int Numerator) {
numerator = Numerator;
}
/// <summary>
/// The numerator of the quotient
/// </summary>
public int Numerator {
get
{
return numerator;
}
}
}