How to gracefully implement a C + + fractional class (Rational)?

Source: Internet
Author: User

What sort of rational realization is elegant?

In my opinion, it should meet the following characteristics

1. Conform to the object-oriented encapsulation feature, data hiding (because there is only one class, no encapsulation and polymorphism is considered).

2. The Declaration and implementation are separated, the interface is clear and natural, there are enough basic functions and not redundant.

3. Simple and Clear Code

4. It is best to read without comment, variable name, method name can be seen in the name of the known meaning

5.do not repeat yourself, do not repeat the work

6. Throw an exception in case of error, abort the program, rather than hide the error in the internal implementation, bury the hidden trouble.

The rational implementation of the following I think is more elegant, it conforms to the above 5 characteristics

1.public, private display of its data hiding features, numerator, denominator class users are inaccessible

2. Provides a basic operation subtraction the inverse of the reciprocal number, and overloads the +,-,*,/operator, which can be used more clearly and naturally

3. The implementation of each method is not complex in itself, the implementation of the GCD function is very concise

4. The method name, the numerator denominator basically can see the name to understand the meaning

5. Subtraction is achieved by adding the opposite number, and division is achieved by multiplying by the reciprocal, which can reflect this

6. When the denominator is zero, the numerator is null to throw an exception when the inverse is obtained


Rational.h

#ifndef rational_#define rational_#include "MyException.h" #include <iostream>using namespace Std;class Rational {public:    Rational (int x, int y);//passing in numerator denominator construct fraction    rational (string s);//construct fractions from string    rational nega ();//Inverse number    rational reci () ;//Countdown    bool IsEqual (Rational that);    Rational add (rational that);//Add    Rational sub (rational that);//Subtract    rational mul (rational that);//Multiplication    Rational Div (rational);//Division    void Output (ostream &out) const;//output Method    int Getnumer () {return numer;}    int Getdenom () {return denom;} Private:    int numer;//numerator    int denom;//denominator    int gcd (int a, int b) const {return (b==0)? A:GCD (b, a% b);} Greatest common divisor}; #endif//Rational_define


Rational.cpp

#include "rational.h" #include "myException.h" #include <cstdlib>using namespace std;    rational::rational (int x, int y) {//pass in numerator denominator construct fraction if (y==0) throw new Illegaldenominatorvalue ();    Numer = x; Denom = y;}    Constructs a fraction from a string rational::rational (string s) {int pos = S.find ('/', 0);    if (pos <= 0 | | pos >= s.length ()-1) throw new Illegalinputexpression ();    Numer = Atoi (S.substr (0,pos). C_STR ());    Denom = Atoi (S.substr (Pos+1,s.length ()-pos-1). C_STR ()); if (Denom = = 0) throw new Illegaldenominatorvalue ();} The inverse number rational rational::nega () {return rational (-numer, denom);}    Inverse Rational Rational::reci () {if (Numer = = 0) throw new noreciprocal (); Return Rational (Denom,numer);} equal bool Rational::isequal (Rational that) {return Numer * that.denom = = Denom * That.numer;} Addition Rational rational::add (rational that) {return rational (Numer * that.denom + denom * that.numer,denom * that.denom); }//subtraction Rational rational::sub (rational that) {return Add (That.nega ());} Multiplication rationalRational::mul (rational that) {return rational (Numer * that.numer, Denom * that.denom);} Division Rational Rational::d IV (Rational that) {return Mul (That.reci ());}       Output void Rational::output (ostream &out) const{int c = gcd (numer,denom);        int c = 1; out<<numer/c<< "/" <<denom/c;    }//Output operator overload ostream& operator<< (ostream& out, const rational& r) {r.output (out); return out;} operator overload rational operator + (rational A, rational b) {return a.add (b);} Rational operator-(rational A, rational b) {return a.sub (b);} Rational operator * (Rational A, rational b) {return A.mul (b);} Rational operator/(rational A, rational b) {return a.div (b);}
MyException.h

Exception classes for various error types#ifndef Myexceptions_#define myexceptions_#include <string> #include <iostream>using namespace std;//illegal denominator valueclass illegaldenominatorvalue{public:illegaldenom Inatorvalue (String themessage = "Denominator must be nonezero!")      {message = Themessage;   } void Outputmessage () {cout << message << Endl;} Private:string message;};/   /illegal input Expressionclass illegalinputexpression{public:illegalinputexpression (String themessage = "illegal      Input Expression ") {message = Themessage;   } void Outputmessage () {cout << message << Endl;} Private:string message;};/  /Countdown Class noreciprocal{public:noreciprocal (String themessage = "No reciprocal with numerator=0") {message      = Themessage;   } void Outputmessage () {cout << message << Endl;} Private:string message;}; #endif

Test.cpp

#include "rational.h" #include "Rational.cpp" using namespace Std;int Main () {    rational A;    Rational B ("quarter");    Rational C ("1/0");    Rational C ("1/");    cout<< "a =  \ t" <<   a       <<endl;    cout<< "b =  \ t" <<   b       <<endl;    cout<< "-a = \ T" <<   A.nega () <<endl;    cout<< "1/b =\t" <<   b.reci () <<endl;    cout<< "A.add (b) =\t" <<   a.add (b) <<endl;    cout<< "A.sub (b) =\t" <<   a.sub (b) <<endl;    cout<< "A.mul (b) =\t" <<   A.mul (b) <<endl;    cout<< "A.div (b) =\t" <<   a.div (b) <<endl;    cout<< "A+b =\t" <<   a+b<<endl;    cout<< "A-=\t" <<   a-b<<endl;    cout<< "A*b =\t" <<   a*b<<endl;    cout<< "A/C =\t" <<   a/b<<endl;    return 0;}

As an example, let's look at how to use this class to solve the problem of "solving a one-dimensional fractional equation such as a/b x+ C/D =/F"

#include "rational.h" #include "Rational.cpp" using namespace Std;int main () {while (1) {cout << "input equation: shaped like A/b x + d/c    = f/e "<<endl;    Char arr[50];    Cin.getline (ARR, 50);   String equation (ARR);    cout << equation <<endl;//A/b x + d/c = f/e int pos_x = equation.find (' x ', 0);    int pos_p = equation.find (' + ', 0);    int pos_e = equation.find (' = ', 0);  Rational Coe (equation.substr (0,pos_x))//A/b Rational B (Equation.substr (pos_p+1,pos_e-pos_p));//d/c Rational C (Equation.substr (Pos_e+1,equation.length ()-pos_e));//f/e//cout<< "Coe =" <<coe<<endl; cout<< "b =" <<b<<endl;    cout<< "C =" <<c<<endl;    if (coe.getnumer () = = 0 && b.isequal (c)) cout<< "X∈q" <<endl;    else if (coe.getnumer () = = 0 &&!b.isequal (c)) cout<< "No Solution" <<endl;    else cout<< "solution x =" << (c-b)/coe<<endl<<endl;    System ("pause"); System ("CLS");}}


The code is as follows

Main.cpp

#include "rational.h" #include "Rational.cpp" using namespace Std;int main () {while (1) {cout << "input equation: shaped like A/b x + d/c    = f/e "<<endl;    Char arr[50];    Cin.getline (ARR, 50);   String equation (ARR);    cout << equation <<endl;//A/b x + d/c = f/e int pos_x = equation.find (' x ', 0);    int pos_p = equation.find (' + ', 0);    int pos_e = equation.find (' = ', 0);  Rational Coe (equation.substr (0,pos_x))//A/b Rational B (Equation.substr (pos_p+1,pos_e-pos_p));//d/c Rational C (Equation.substr (Pos_e+1,equation.length ()-pos_e));//f/e//cout<< "Coe =" <<coe<<endl; cout<< "b =" <<b<<endl;    cout<< "C =" <<c<<endl;    if (coe.getnumer () = = 0 && b.isequal (c)) cout<< "X∈q" <<endl;    else if (coe.getnumer () = = 0 &&!b.isequal (c)) cout<< "No Solution" <<endl;    else cout<< "solution x =" << (c-b)/coe<<endl<<endl;    System ("pause"); System ("CLS");}}

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

How to gracefully implement a C + + fractional class (Rational)?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.