始めに
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;
}
終わりに
機能的には最低限なので、必要に応じてブラッシュアップをした方が良いでしょう。