Click here to Skip to main content
Click here to Skip to main content

CFraction - a double / fraction / string conversion class

, 17 Apr 2000
Rate this:
Please Sign up or sign in to vote.
A class that converts between doubles, strings and fractional representations.

Introduction

The CFraction class is a handy class when dealing with doubles 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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Dean Wyant
Web Developer
United States United States
No Biography provided

Comments and Discussions

 
QuestionSmall error in formula? PinmemberPhilip Dam8-Dec-08 23:50 
AnswerRe: Small error in formula? PinmemberDean Wyant19-Dec-08 4:36 
QuestionHi. i need some urgent help PinmemberMehran Gul22-Sep-08 6:14 
AnswerRe: Hi. i need some urgent help PinmemberDean Wyant23-Sep-08 4:14 
QuestionLicense Pinmemberjanetec28-May-07 6:07 
AnswerRe: License PinmemberDean Wyant29-May-07 3:36 
QuestionHow do you install the class Pinmember_matt_n00b_2-Nov-05 14:03 
AnswerRe: How do you install the class PinmemberDean Wyant3-Nov-05 6:16 
Generalfractions Pinsussbrieanah10-Apr-03 20:00 
GeneralRe: fractions PinmemberDean Wyant11-Apr-03 6:59 
GeneralNegative Number Bug PinmemberDean Wyant16-Jan-02 9:39 
GeneralRe: Negative Number Bug PinmemberDean Wyant17-Jan-02 8:20 
GeneralThanks PinsussJohn1-Nov-00 10:48 
Generalproject PinsussMelissa20-Oct-00 9:43 
GeneralRe: project PinmemberGene Zawadzki17-Apr-01 14:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 18 Apr 2000
Article Copyright 2000 by Dean Wyant
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid