12,248,946 members (22,569 online)
alternative version

103.6K views
37 bookmarked
Posted

# CFraction - a double / fraction / string conversion class

, 17 Apr 2000
 Rate this:
A class that converts between doubles, strings and fractional representations.

## Introduction

The `CFraction` class is a handy class when dealing with `double`s and fractions. You can use it like a `double` and do anything you would do with a `double`, plus you assign strings to it. When you need to get a string representation, use one of the methods returning a `CString`. Or, if you do not use `CString`, there are methods for `char *`.

## Example usage:

```CFraction F1,F2;
double D;
CString S;

// Assignment
F1 = 5.126;        // double
F2 = "5.126";      // string
F1 = "5 63/500";   // string with fraction

D = F1;            // double = CFraction
F2 = D;            // CFraction = double

// Math
F1 = F2 + D;       // Mix and match them
F2 = F1/D;
// any math operation you want

// Comparison
if ((F1 > D) || (F1 < F2))
D = F2/F1;

F2 = 15.0135;      // 5 27/2000

S = F2.ToString(); // Returns "5 27/2000"

// Another version of ToString limits
// the denominator to the passed maximum value.
S = F2.ToString(64);
// Returns "15 1/64" because 64 was exceeded
// with first estimate 1/74

// Or, if you are working with stock prices
// and you only want to show fractions when
// the deniminator is 2,4,8,16,32,64,128,or 256
// or up to passed maximum denominator ( <= 256)
S = F2.ToStockString();
// Returns "15.0135" because fraction is not a normal stock price

// Or, force the denominator to be a valid
// stock price denominator up to passed Max. Den.
S = F2.ForceToStockString();   // Returns closest stock price "15 3/256"
S = F2.ForceToStockString(64); // Returns closest stock price "15 1/64"

// If you are like me, you are wondering what it will do with PI :-)
F1 = 3.1415926535897932384626433832795;
// From Calculator - well beyond doubles capability
S = F1.ToString(); // Returns  "3 3612111/25510582"
// The difference is about 5.79087e-16

// You can increase precision when you know
// that a value has a very large denominator.
// A double passed to ToString specifies the allowed error to shoot for.
// Warning: Using a smaller allowed error
// can cause invalid results for fractions that
// can be accurately converted using a larger
// allowed error. Also, since __int64 is used,
// a denomintor cannot exceed 18 or 19 digits.
S = F1.ToString(10.0e-50);
// Pushing it way up returns "3 36853866/260280919"
// The difference to double precision
// is 0 because doubles accuracy was reached.
// The actual difference is about 1.27274e-16.

// If you have access to a more accurate type (like Calculator does),
// you can replace double in the code
// to increase accuracy. You can also
// replace __int64 if you want a denominator >  18 digits.

// Lets try a resonable maximum denominator fo PI, like 999
S = F1.ToString(999); // returns "3 16/113"

// The first three estimates this class gives
// for PI are 3 1/7, 3 15/106, and 3 16/113
```

The algorithm was developed using the formula for converting a decimal fraction to a string fraction. Any fractional part can be represented as:

1/(I1 + 1/(I2 + 1/(I3 + 1/In ...

where I1 is the integer part of the reciprocal of the fraction and I2 is the integer part of the reciprocal minus I1 ... etc. To determine the integer numerator and denominator, the expression can be reduced. It turns out that the numerator is simpler to calculate than the denominator, so the denominator can simply be determined by dividing the numerator by the original decimal.

Reduction of 1/(I1 + 1/(I2 + 1/(I3 + 1/In ... ))) - There is a way to mathematically reduce this elegantly. However, I think a simple step by step algebraic approach will be understood by more readers.

• 1 I term: 1/I1 Numerator N1 = 1
• 2 I terms: 1/(I1 + 1/I2) Multiply by I2/I2 = I2/((I1*I2) + 1),

Numerator N2 = I2

• 3 I terms: 1/(I1 + 1/(I2 + 1/I3)) Multiply by I3/I3 = 1/(I1 + I3/(I2*I3) + 1)

then Multiply by ((I2*I3) + 1)/((I2*I3) + 1) = ((I2*I3) + 1)/(I1*((I2*I3) + 1) + I3),

Numerator N3 = ((I2*I3) + 1)

• 4 I terms: ...

Multiply by I4/I4 = 1/(I1 + 1/(I2 + I4/(I3*I4) + 1))

Multiply by (I3*I4) + 1) = 1/(I1 + ((I3*I4) + 1)/(I2*((I3*I4) + 1) + I4)).. ,

Numerator N4 = I2*((I3*I4) + 1) + I4

As we continue, a pattern to the numerators appears showing that N1 = 1, N2 = I2, and Nn = In*Nn-2 + Nn-3 .

This is fairly simple to code.

A list of licenses authors might use can be found here

## Share

 Web Developer United States
No Biography provided

## You may also be interested in...

 First Prev Next
 Small error in formula? Philip Dam8-Dec-08 23:50 Philip Dam 8-Dec-08 23:50
 Re: Small error in formula? Dean Wyant19-Dec-08 4:36 Dean Wyant 19-Dec-08 4:36
 Hi. i need some urgent help Mehran Gul22-Sep-08 6:14 Mehran Gul 22-Sep-08 6:14
 Re: Hi. i need some urgent help Dean Wyant23-Sep-08 4:14 Dean Wyant 23-Sep-08 4:14
 License janetec28-May-07 6:07 janetec 28-May-07 6:07
 Re: License Dean Wyant29-May-07 3:36 Dean Wyant 29-May-07 3:36
 How do you install the class _matt_n00b_2-Nov-05 14:03 _matt_n00b_ 2-Nov-05 14:03
 Re: How do you install the class Dean Wyant3-Nov-05 6:16 Dean Wyant 3-Nov-05 6:16
 fractions brieanah10-Apr-03 20:00 brieanah 10-Apr-03 20:00
 Re: fractions Dean Wyant11-Apr-03 6:59 Dean Wyant 11-Apr-03 6:59
 Negative Number Bug Dean Wyant16-Jan-02 9:39 Dean Wyant 16-Jan-02 9:39
 Re: Negative Number Bug Dean Wyant17-Jan-02 8:20 Dean Wyant 17-Jan-02 8:20
 Thanks John1-Nov-00 10:48 John 1-Nov-00 10:48
 project Melissa20-Oct-00 9:43 Melissa 20-Oct-00 9:43