Operator overloading functions as member functions of classes – reduction of rational numbers

Directory

1. Topic

Two, the code

3. Algorithm analysis

(1) Mathematical expression

(2) Code implementation

a) + operator overloaded function

2) Optimization function (realize rational number reduction)


1. Title

The addition, subtraction, multiplication, and division of two rational number objects is realized by overloading the operator as a member function of the class;

A rational number is a number that can be converted into a fraction, such as 2/3, 533/920, which are all rational numbers, while the root number 2, Π, etc. are irrational numbers.

In C++, rational numbers are not defined in advance, and a rational number class can be declared when necessary, and the numerator and denominator of rational numbers are stored in the nume and deno variables respectively, and various operations on rational numbers can be realized by overloading operators . You can write an optimization function optimize, which makes the rational number reduce the common denominator, that is, there is no common divisor (except 1) between the numerator and denominator of the saved rational number. It can only be executed when creating a rational number object, and it can also be executed after performing various operations, so as to ensure that the stored rational numbers are optimal.

2. Code

#include<iostream>
using namespace std;
#include <cmath>

class Rational //Define the rational number class
{
public:
Rational(int x=0,int y=1); //class constructor
void print(); //print rational numbers
Rational operator + (Rational a); //The operator overload function (member function) of the class realizes the addition of rational numbers
private:
int nume; //molecule
int deno; // denominator
void optimize(); //Optimize the function to realize the reduction of rational numbers
};
void Rational::optimize() //Optimize the function to realize the reduction of rational numbers
{
int gcd,i; //gcd stores the larger numerator and denominator, i records the common divisor of the update
if(nume==0) //①If the numerator is 0, then the denominator is set to 1, return, and the reduction ends
{
deno=1;
return;
}
                                 //②The numerator is not 0, continue to reduce the operation
gcd=(abs(nume)>abs(deno)?abs(nume):abs(deno)); //gcd is the larger of the numerator and denominator
if(gcd==0) //If it is 0, no reduction is needed, return, and end the reduction operation
return;
for(i=gcd;i>1;i--) //for loop, starting from gcd, successively -1, judging whether it is a common divisor, and returning if one is found (the greatest common divisor)
{
if((nume%i==0) & amp; & amp;(deno%i)==0) //Judge whether it is a common divisor
break;
}
nume/=i; //Update the numerator and denominator according to the found greatest common divisor
deno/=i;
if(nume<0 & amp; & amp;deno<0) //If the numerator and denominator are both negative, the result is positive, so both are changed to positive
{
nume=-nume;
deno=-deno;
}
else if(nume<0||deno<0) //If one of the numerator and denominator is negative, the result is negative, the numerator is adjusted to be negative, and the denominator is adjusted to be positive
{
nume=-abs(nume);
deno=abs(deno);
}
}
Rational::Rational(int x,int y) //Constructor definition, call optimization function at the same time, continue to reduce rational numbers
{
nume=x;
deno=y;
optimize();
}
void Rational::print() //print rational numbers
{
cout<<nume;
if(nume!=NULL) //①The molecule is not 0
cout<<"/"<<deno<<endl;
else //②The numerator is 0
cout<<endl;
}
//What the function returns is not a reference type, because it cannot be used as an lvalue
Rational Rational::operator + (Rational a) // + operator overloading function to implement the addition operation of classes (user-defined data types)
{
Rational r; //Define a temporary variable, automatically call the constructor of the class, occupy the stack area, and the system will automatically call the destructor after the program ends to release the memory
r.deno=a.deno*deno;
r.nume=a.nume*deno + a.deno*nume;
r.optimize(); //It also needs to be reduced after the calculation
return r;
}
int main()
{
Rational r1(3,14),r2(4,14),r3;
r1. print();
r2. print();
r3=r1 + r2;
r3. print();
return 0;
}

3. Algorithm Analysis

add rational numbers

(1) Mathematical expression

When two rational numbers \frac{a}{b} and \frac{c}{d} When adding, you can get the formula

\frac{a*d + b*c}{b*d}

The numerator and denominator are stored separately

Molecule = a*d + b*c

denominator=b*d

After the operation is completed, it is necessary to continue to optimize the word rational number,

This operation can be achieved by overloading the operator ” + “.

(2) Code implementation

1) + operator overloaded function

the code

Rational Rational::operator + (Rational a) // + operator overloading function to implement the addition operation of classes (user-defined data types)
{
Rational r; //Define a temporary variable, automatically call the constructor of the class, occupy the stack area, and the system will automatically call the destructor after the program ends to release the memory
r.deno=a.deno*deno;
r.nume=a.nume*deno + a.deno*nume;
r.optimize(); //It also needs to be reduced after the calculation
return r;
}

analyze

After the operator is overloaded, when performing rational number operations, it only needs to be written like the operation of the basic type, which brings great convenience to the user and is very intuitive.

r3=r1+r2;

When executed, C++ can be interpreted as

r3=r1.operator + (r2);

It can be seen from this that when the C++ system processes the arithmetic expression “r1 + r2”, the processing of the expression is automatically converted into a call to the member operator overloaded function operator + (r1.operator + (r2)), The operator + is invoked through the object on the left of the “+” operator, and the object on the right of the “+” is used as the actual parameter of the function call.

In this way, the object on the left side of the binary operator is implicitly passed to the operator + function by the system through the this pointer. Therefore, if the binocular operator function is overloaded as a member function of a class, only one formal parameter needs to be written in its parameter table.

But it must be required that the first parameter of the operation expression (the operand on the left side of the operator) is a class object. And it has the same return type as the operator function. This is because the member functions of the class must be called through the object of the class, and as long as the operator overloaded function returns the same type as the object, the operation is meaningful.

2) Optimization function (realize rational number reduction)

the code

void Rational::optimize() //Optimize the function to realize the reduction of rational numbers
{
int gcd,i; //gcd stores the larger numerator and denominator, i records the common divisor of the update
if(nume==0) //①If the numerator is 0, then the denominator is set to 1, return, and the reduction ends
{
deno=1;
return;
}
//②The numerator is not 0, continue to reduce the operation
gcd=(abs(nume)>abs(deno)?abs(nume):abs(deno)); //gcd is the larger of the numerator and denominator
if(gcd==0) //If it is 0, no reduction is needed, return, and end the reduction operation
return;
for(i=gcd;i>1;i–) //for loop, starting from gcd, successively -1, judging whether it is a common divisor, and returning if one is found (the greatest common divisor)
{
if((nume%i==0) & amp; & amp;(deno%i)==0) //Judge whether it is a common divisor
break;
}

nume/=i; //Update the numerator and denominator according to the found greatest common divisor
deno/=i;

if(nume<0 & amp; & amp;deno<0) //If the numerator and denominator are both negative, the result is positive, so both are changed to positive
{
nume=-nume;
deno=-deno;
}
else if(nume<0||deno<0) //If one of the numerator and denominator is negative, the result is negative, the numerator is adjusted to be negative, and the denominator is adjusted to be positive
{
nume=-abs(nume);
deno=abs(deno);
}
}

analyze

Steps to Find the Greatest Common Divisor

①Initial greatest common divisor gcd

gcd=(abs(nume)>abs(deno)?abs(nume):abs(deno)); //gcd is the larger of the numerator and denominator

② Determine whether it is a common divisor

for(i=gcd;i>1;i–) //for loop, starting from gcd, successively -1, judging whether it is a common divisor, and returning if one is found (the greatest common divisor)
{
if((nume%i==0) & amp; & amp;(deno%i)==0) //Judge whether it is a common divisor
break;
}