C++の簡単な分数クラス

#始めに
C++で分数を扱えるクラスを作成しました。
分母、分子共に整数(int)型と制約があります。
四則演算はサポートしています。
使い方は「main.cpp」を参考にしてください。

#分数クラス(nsFraction)

```C++:nsFraction.h
//---------------------------------------------------------------------------
#ifndef nsFractionH
#define nsFractionH
//---------------------------------------------------------------------------
#include<string>

/**
 * C++の整数分数クラス
 *
 */
class nsFraction
{
private:
	//  分子
	int numerator;
	//  分母
	int denominator;
private:
	// 最大公約数を求める
	static int gcdi(int a, int b);
public:
	//分数を作る
	nsFraction();
	//分数を作る
	nsFraction(const nsFraction& him);
	//分数を作る
	nsFraction(int numerator, int denominator);

	// 約分を行う
	void reduction();
	// 引数の分数を加える
	void addition(const nsFraction& qf);
	// 引数の分数を引く
	void subtraction(const nsFraction& qf);
	// 引数の分数を掛ける
	void multiplication(const nsFraction& qf);
	// 引数の分数を割る
	bool division(const nsFraction& qf);
	// 分子を返す
	int  getNumerator() const;
	// 分母を返す
	int  getDenominator() const;
	// 分子,分母をセット
	void setFraction(int n,int d);
	// 分数をセット
	void setFraction(const nsFraction& him);
	// 0か調べる
	bool isZero() const;
	// 0をセット
	void setZero();
	// 文字列化
	std::string toString() const;
	//double化(分母が０の場合は０を返す)
	double toDouble();

public:
	//分数の足し算
	nsFraction operator+(const nsFraction& fraction) const;
	//分数の引き算
	nsFraction operator-(const nsFraction& fraction) const;
	//分数の掛け算
	nsFraction operator*(const nsFraction& fraction) const;
	//分数の割り算
	nsFraction operator/(const nsFraction& fraction) const;
public:
	//分数の掛け算
	nsFraction operator*(int val) const;

};

#endif
```

```C++:nsFraction.cpp
#include "nsFraction.h"

/**分数を作る
*/
nsFraction::nsFraction()
{
	setFraction(0, 0);
}
/**分数を作る
* @param him 分数
*/
nsFraction::nsFraction(const nsFraction& him)
{
	this->numerator   = him.numerator;
	this->denominator = him.denominator;
}

/**分数を作る
* @param numerator 分子
* @param denominator 分母
*/
nsFraction::nsFraction(int numerator, int denominator)
{
	this->numerator = numerator;
	this->denominator = denominator;

	reduction();
}
/**
* 最大公約数を求める
* @param a
* @param b
* @return
*/
int nsFraction::gcdi(int a, int b)
{
	while (b > 0)
	{
		int c = a;
		a = b;
		b = c % b;
	}
	return a;
}
/**
* 約分を行う
*/
void nsFraction::reduction()
{
	//0チェック
	if(isZero() == true)
	{
		setZero();
		return;
	}
	//最大公約数を得る
	int gcdi = nsFraction::gcdi(numerator, denominator);
	//分母、分子を最大公約数で割る
	numerator = numerator / gcdi;
	denominator = denominator / gcdi;
}
/**
	* 引数の分数を加える
	* @param nsFraction
	* @return
	*/
void nsFraction::addition(const nsFraction& qf)
{
	//0チェック
	bool tz = this->isZero();
	bool hz = qf.isZero();
	//計算
	if(tz == false && hz == false)
	{
		numerator    = qf.denominator * numerator + qf.numerator * denominator;
		denominator *= qf.denominator;
		
		reduction();
	}
	else if(tz == true && hz == false)
	{
		numerator    = qf.numerator;
		denominator  = qf.denominator;
		
		reduction();
	}
	else if(tz == false && hz == true)
	{
		reduction();
	}
	else
	{
		setZero();
	}
}
/**
	* 引数の分数を引く
	* @param nsFraction 引かれる数
	* @return
	*/
void nsFraction::subtraction(const nsFraction& qf)
{
	//0チェック
	bool tz = this->isZero();
	bool hz = qf.isZero();
	//計算
	if (tz == false && hz == false)
	{
		numerator    = qf.denominator * numerator - qf.numerator * denominator;
		denominator *= qf.denominator;

		reduction();
	}
	else if(tz == true && hz == false)
	{
		numerator    = -1 * qf.numerator;
		denominator  = qf.denominator;
		
		reduction();
	}
	else if(tz == false && hz == true)
	{
		reduction();
	}
	else
	{
		setZero();
	}
}
/**
* 引数の分数を掛ける
* @param nsFraction
* @return
*/
void nsFraction::multiplication(const nsFraction& qf)
{
	//0チェック
	bool tz = this->isZero();
	bool hz = qf.isZero();
	//計算
	if (tz == false && hz == false)
	{
		denominator *= qf.denominator;
		numerator   *= qf.numerator;

		reduction();
	}
	else
	{
		setZero();
	}
}
/**
* 引数の分数を割る
* @param nsFraction 割られる数
* @return true 成功 false 0で割った
*/
bool nsFraction::division(const nsFraction& qf)
{
	//0チェック
	bool tz = this->isZero();
	bool hz = qf.isZero();

	//計算
	if (tz == false && hz == false)
	{
		denominator *= qf.numerator;
		numerator   *= qf.denominator;

		reduction();
	}
	else if(tz == true && hz == false)
	{
		setZero();
	}
	else if(tz == false && hz == true)
	{
		//0で割って失敗
		return false;
	}
	else
	{
		setZero();
	}
    return true;
}
/**
* 分子を返す
* @return
*/
int nsFraction::getNumerator() const
{
	return numerator;
}
/**
* 分母を返す
* @return
*/
int nsFraction::getDenominator()  const
{
	return denominator;
}
/**
* 分子,分母をセット
* @return
*/
void nsFraction::setFraction(int n,int d)
{
	numerator   = n;
	denominator = d;
}
/**
* 分数をセット
* @param him 分数
* @return
*/
void nsFraction::setFraction(const nsFraction& him)
{
	this->numerator   = him.numerator;
	this->denominator = him.denominator;
}
/**
* 文字列化
* @return
*/
std::string nsFraction::toString() const
{
	//0の時は0を返す
	if(isZero()== true)
	{
		return std::string("0");
	}
	//分母が1のときは分子だけ返す
	if (denominator == 1)
	{
		return std::to_string(numerator);
	}
	return std::to_string(numerator)  + "/"  + std::to_string(denominator);
}

/**
* double化
* @return 分数の計算結果　(分母が０の場合は０を返す)
*/
double nsFraction::toDouble()
{
	//分母が0のときは0を返す
	if (denominator == 0)
	{
		return 0;
	}
	double val = static_cast<double>(numerator)/static_cast<double>(denominator);

	return val;
}

//-----------------------------
// 0か調べる
//-----------------------------
bool nsFraction::isZero() const
{
	bool iz = false;
	if(numerator == 0 ||  denominator == 0)
	{
		iz = true;
	}
	return iz;
}
//-----------------------------
// 0をセット
//-----------------------------
void nsFraction::setZero()
{
	numerator   = 0;
	denominator = 0;
}
//-----------------------------
//分数の足し算
//-----------------------------
nsFraction nsFraction::operator+(const nsFraction& fraction) const
{
	nsFraction Src(*this);
	// 引数の分数を加える
	Src.addition(fraction);
	//約分
	Src.reduction();

	return Src;
}
//-----------------------------
//分数の引き算
//-----------------------------
nsFraction nsFraction::operator-(const nsFraction& fraction) const
{
	nsFraction Src(*this);
	// 引数の分数を引く
	Src.subtraction(fraction);
	//約分
	Src.reduction();

	return Src;
}
//-----------------------------
//分数の掛け算
//-----------------------------
nsFraction nsFraction::operator*(const nsFraction& fraction) const
{
	nsFraction Src(*this);
	//掛け算
	Src.multiplication(fraction);
	//約分
	Src.reduction();

	return Src;
}
//-----------------------------
//分数の掛け算
//-----------------------------
nsFraction nsFraction::operator*(int val) const
{
	nsFraction Src(*this);
	//分子を掛け算する
	Src.numerator *= val;
	//約分
	Src.reduction();

	return Src;
}

//-----------------------------
//分数の割り算
//-----------------------------
nsFraction nsFraction::operator/(const nsFraction& fraction) const
{
	nsFraction Src(*this);
	//割り算
	Src.division(fraction);
	//約分
	Src.reduction();

	return Src;
}

```

#デモ用メイン関数(main)

```C++:main.cpp
#include <iostream>
#include <stdio.h>
#include "nsFraction.h"

int main(int argc, char* argv[])
{
	//---- 分数計算デモ ---

	//(1) 1/2
	nsFraction f12(1,2);
	std::cout << "(1) " << f12.toString() << std::endl;
	//(2) 1/5
	nsFraction f15(1,5);
	std::cout << "(2) " << f15.toString() << std::endl;
	//(3) 1/2+1/5 = 7/10
	nsFraction fplus = f12 + f15;
	std::cout << "(3) " << fplus.toString() << std::endl;
	//(4) 1/2-1/5 = 3/10
	nsFraction fmuinus = f12 - f15;
	std::cout << "(4) " << fmuinus.toString() << std::endl;
	//(5) 1/2×1/5 = 1/10
	nsFraction fmultiplication = f12 * f15;
	std::cout << "(5) " << fmultiplication.toString() << std::endl;
	//(6) 1/2÷1/5 = 5/2
	nsFraction fdivision = f12 / f15;
	std::cout << "(6) " << fdivision.toString() << std::endl;

	//止め
	getchar();

	return 0;
}
```

#終わりに
機能的には最低限なので、必要に応じてブラッシュアップをした方が良いでしょう。