11,428,876 members (59,429 online)

# Fraction class in C#

, 15 Feb 2005 CPOL
 Rate this:
An article representing floating point numbers as fractions.

## Introduction

This article demonstrates how to remove the problem of limited precision when numbers such as 1/10, 1/7, 1/3, etc. are represented in a floating point variable type in C#. Yes, you guessed it right, this problem can be solved by storing such numbers in a fraction format. As a fraction object stores its numerator and denominator as integer variables, there is no loss of accuracy. For this purpose, I have written a simple C# class representing fractions. It can be used in various applications, e.g., equation solving, matrix transformations, etc.

## Features of class

The class contains a variety of overloaded constructors and operators for certain situations. It also throws certain exceptions, e.g., when denominator is tried to assign a 0 value, when the result of an arithmetic exceeds the limit (range), etc. One more feature is the automatic normalization (simplification) of fractions. The class uses data type 'long integer' for storing numerator and denominator, hence its range is upper bounded by the range of `Int64` in .NET framework.

## Using the code

The class includes a variety of constructors, e.g., one that takes an integer like 123, one that takes a double like 156.25, one that takes a string that has all the above qualities (e.g., string can be "32/77" or "213" or "321.44"), one that takes values of numerator and denominator like 231 and 101, and, of course, a parameter-less constructor for a "zero" fraction stored as 0/1.

```Fraction frac=new Fraction(); // we'll get 0/1
frac=new Fraction(1,5);       // we'll get 1/5
frac=new Fraction(25);        // we'll get 25/1
frac=new Fraction(9.25);      // we'll get 37/4
frac=new Fraction("6.25");    // we'll get 25/4

// we can enter anything like "213" or
// "23/3" or "4.27"

Console.WriteLine( frac );
// displays the current value of frac1 object;```

Operators overloaded (overloaded for fractions, integers and doubles) for `Fraction` object include:

• Unary: `-` (Negation)
• Binary `+`, `-`, `*`, `/`
• Relational operators such as `==`, `!=`, `<`, `>`, `<=`, `>=`.
```Fraction frac=new Fraction("1/2"); // initialize a fraction with 1/2
Console.WriteLine( frac+2.5 );     // will display 3```

Overloaded conversion further enhances the capabilities of the class. See how simple it is to work with fractions:

```Fraction frac="1/2" // implicit cast from string to
frac="22.5"         // implicit cast from string to fraction
frac=10.25          // implicit cast from double to fraction
frac=15             // implicit cast from integer/long to fraction```

Finally, as an exercise, guess the output of the following code:

```Fraction f=0.5;                 // initialize frac=1/2
Console.WriteLine( f-0.25 );    // Yes, you are right. "1/4" is displayed
Console.WriteLine( f+"1/4" );
// not sure??? It will display "3/4" because "1/4" has
// been converted to fraction and then added to our frac object```

## Implementation details

The class uses simple mathematics to do all the work. Let us see some of these simple techniques:

• To convert a double to a fraction, we keep multiplying the given double number with 10 until it is converted to an integer number.
• To convert a given string to a fraction, we treat all the value before "/" as numerator and after "/" as denominator.
• To normalize a fraction, we divide its numerator and denominator by their GCD (found by famous Euler's formula).
• To add two fractions, we use simple school formula to get numerator and denominator of the resultant fraction and then normalize it:
```Numerator = frac1.Numerator*frac2.Denominator
+ frac2.Numerator*frac1.Denominator;
Denominator = frac1.Denominator*frac2.Denominator;```
• To overload arithmetic operators for integers and doubles, we first convert them to fractions and then perform the operation.

## Applications

There are a lot of applications of `Fraction` class. An example is a matrix class, see my article on Matrix class in C#.

## History

Version 2.0

• Changed `Numerator` and `Denominator` from `Int32` (integer) to `Int64` (long) for increased range.
• Renamed `ConvertToString()` to `ToString()`.
• Added the capability of detecting/raising overflow exceptions.
• Fixed the bug that very small numbers, e.g. 0.00000001, could not be converted to fraction.
• Fixed other minor bugs.

Version 2.1

Version 2.2 (changes by Marc Brooks and Jeffrey Sax).

• Less overflows by finding the GCD for Add [Jeffery Sax] and Multiply [Marc C. Brooks]
• Understands and handles NaN, PositiveInfinity, NegativeInfinity just like `double` [Marc C. Brooks]
• Fixed several uses of `int` where `long` was correct [Marc C. Brooks]
• Made value-type (`struct`) [Jeffery Sax]
• Added `ToInt32()`, `ToInt64()` which throw for invalid (NaN, PositiveInfinity, NegativeInfinity) [Marc C. Brooks]
• Removed redundant `Value` property [Jeffery Sax]
• Added explicit conversion to `Int32` and `Int64` [Marc C. Brooks]
• Better handling of exceptions [Marc C. Brooks]
• Reorganized code, added XML doc and regions [Marc C. Brooks]
• Proper implementations of `Equals` [Marc C. Brooks, Jeffery Sax]
• Uses `Math.Log(xx,2)` and `Math.Pow(xx,2)` to get the best accuracy possible when converting `double`s [Marc C. Brooks, Jeffery Sax]

Version 2.3 (changes by Marc Brooks and Jeffrey Sax)

• Fixed double-to-fraction logic to use continued fraction rules to get best possible precision [bug fix for Syed Mehroz Alam, idea from Jeffery Sax]
• Added static readonly values for NaN, PositiveInfinity, NegativeInfinity [idea from Jeffery Sax]
• Moved comparisons into an implementation of `IComparer` [idea from Jeffery Sax]
• No longer throws for NaN(s) involved in Add, Subtract, Multiply, Divide operations [idea from Jeffery Sax]
• Added static readonly values for `Zero`, `MinValue`, `MaxValue`, `Epsilon` to better mirror `double` [Marc C. Brooks]
• Added `IsInfinity` to better mirror `double` [Marc C. Brooks]
• Added modulus and % operators [Marc C. Brooks]

## Share

Software Developer
Pakistan

Syed Mehroz Alam, living in Karachi, Pakistan, is a developer focusing Microsoft technologies. He has completed his bachelors as a Computer Systems Engineer in 2006 and is currently pursuing a Masters degree in Computer Science. He loves to learn, discover and master all aspects of .NET and SQL Server. Mehroz has developed rich internet enterprise applications using Silverlight in addition to the traditional ASP.NET and Windows Forms applications. He has worked with all three components of SQL Business Intelligence Studio: SSIS, SSRS and SSAS for developing BI Solutions and Data warehouse. He loves to write complex TSQL queries and evaluate his skills by participating in various TSQL Challenges. His blog can be viewed at http://smehrozalam.wordpress.com.

 First Prev Next
 Globalization issue Anders Eriksson17-Feb-14 3:58 Anders Eriksson 17-Feb-14 3:58
 Handling Radios & Percents Duane McKinney19-Jun-13 7:46 Duane McKinney 19-Jun-13 7:46
 Re: Square roots [modified] mla15425-Jul-12 6:13 mla154 25-Jul-12 6:13
 Unit tests for this class using NUnit Syed Mehroz Alam16-Feb-10 3:07 Syed Mehroz Alam 16-Feb-10 3:07
 Thanks a million! anhldbk27-Oct-09 20:59 anhldbk 27-Oct-09 20:59
 Also check out the Fraction class from Apache Sire40427-Mar-09 4:03 Sire404 27-Mar-09 4:03
 Thanks for this class! However, if you need to reduce fractions with a max denominator (accepting rounding errors), check out the Apache implementation: Manual: http://commons.apache.org/math/apidocs/org/apache/commons/math/fraction/Fraction.html[^] Source (java, very easy to convert): http://www.apache.org/dev/version-control.html[^] -------------------- No one is perfect. Welll, there was this guy... but we killed him. coolquotescollection.com
 gcd in binary TheKing28-Mar-07 11:35 TheKing2 8-Mar-07 11:35
 Simple change Daenris24-Sep-06 14:26 Daenris 24-Sep-06 14:26
 Re: Simple change Daenris24-Sep-06 14:33 Daenris 24-Sep-06 14:33
 Re: Simple change dodiggitydag12-Oct-06 16:10 dodiggitydag 12-Oct-06 16:10
 Re: Simple change Nick Alexeev12-Oct-14 10:40 Nick Alexeev 12-Oct-14 10:40
 A very good class Mina Momtaz13-May-06 23:33 Mina Momtaz 13-May-06 23:33
 Bug in CompareTo(Fraction right) method. Marc Brooks9-Nov-05 8:25 Marc Brooks 9-Nov-05 8:25
 Some improvements for this class. Marc C. Brooks20-Dec-04 14:22 Marc C. Brooks 20-Dec-04 14:22
 Re: Some improvements for this class. Syed Mehroz Alam20-Dec-04 21:06 Syed Mehroz Alam 20-Dec-04 21:06
 Re: Some improvements for this class. Jeffrey Sax20-Dec-04 22:28 Jeffrey Sax 20-Dec-04 22:28
 Re: Some improvements for this class. Marc Brooks11-Jan-05 11:26 Marc Brooks 11-Jan-05 11:26
 Re: Some improvements for this class. Hardy Wang7-Mar-09 8:01 Hardy Wang 7-Mar-09 8:01
 A few suggestions Jeffrey Sax16-Dec-04 17:19 Jeffrey Sax 16-Dec-04 17:19
 Re: A few suggestions Syed Mehroz Alam20-Dec-04 20:54 Syed Mehroz Alam 20-Dec-04 20:54
 Re: A few suggestions Jeffrey Sax20-Dec-04 22:45 Jeffrey Sax 20-Dec-04 22:45
 Last Visit: 31-Dec-99 19:00     Last Update: 3-May-15 6:43 Refresh 1