1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

始めに

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

分数クラス(nsFraction)

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化(分母が0の場合は0を返す)
	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
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 分数の計算結果 (分母が0の場合は0を返す)
*/
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)

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;
}

終わりに

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

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?