C++で分数class

~~競技プログラミング用に~~C++で分数を扱えるクラスを作りました
（処理速度は考えてません

参考
- http://blog.livedoor.jp/add20/archives/2285655.html 
- http://www002.upp.so-net.ne.jp/ys_oota/effec/chapter4.htm

コードは下記（# コード）

- 2019/07/25 var.1.0.0
- 2019/07/27 var.1.1.0
    - swap()などをstdを使用するように変更
    - dight()を削除
    - ```Fraction operator+(long long b);```などを削除
    - 四則演算の順序が逆でもできるように変更

# 内容
```cpp
Fraction a(2, 5);
```
で、2/5という分数のクラスを作成することができます

また

```cpp
Fraction a(3);
```
で、3（ = 3/1）を作成できます

一応、四則演算等は使用できます

```toString()```でStringに、```toLongDouble()```でlong doubleに変換できます

# メモ
1. 四則演算の相手がint型であっても、コンパイラが自動的にintをFractionに変換してくれる
2. 四則演算の順序について（aはFraction型）

```cpp
Fraction operator*(const Fraction& b);
```
　　だと、a * 2しかできないが、

```cpp
friend const Fraction operator*(const Fraction& a, const Fraction& b);
```
　　にして、色々すると、2 * aもできるようになる

# コード
## Fraction.h
```cpp:Fraction.h
#include <string>

#pragma once
class Fraction
{
private:
	long long numer;	// 分子
	long long denom;	// 分母

	friend const bool operator==(const Fraction& a, const Fraction& b);
	friend const bool operator!=(const Fraction& a, const Fraction& b);
	friend const bool operator>=(const Fraction& a, const Fraction& b);
	friend const bool operator<=(const Fraction& a, const Fraction& b);
	friend const bool operator>(const Fraction& a, const Fraction& b);
	friend const bool operator<(const Fraction& a, const Fraction& b);

	friend const Fraction operator+(const Fraction& a, const Fraction& b);
	friend const Fraction operator-(const Fraction& a, const Fraction& b);
	friend const Fraction operator*(const Fraction& a, const Fraction& b);
	friend const Fraction operator/(const Fraction& a, const Fraction& b);

public:
	Fraction();
	Fraction(long long);
	Fraction(long long, long long);
	Fraction(const Fraction&);

	void set(long long, long long);
	void set(const Fraction&);
	void setNumer(long long);
	void setDenom(long long);

	long long getNumer();
	long long getDenom();

	static long long gcd(long long, long long);	// 最大公約数
	static long long lcm(long long, long long);	// 最小公倍数
	void normal();	// 約分

	std::string toString();
	long double toLongDouble();

	bool equals(const Fraction&) const;
	long long compare(const Fraction&) const;

	Fraction& operator=(const Fraction& b);

	Fraction& operator+=(const Fraction& b);
	Fraction& operator-=(const Fraction& b);
	Fraction& operator*=(const Fraction& b);
	Fraction& operator/=(const Fraction& b);

	Fraction operator+();
	Fraction operator-();

	Fraction& operator++();
	Fraction  operator++(int);

	Fraction& operator--();
	Fraction  operator--(int);
};
```

## Fraction.cpp
```cpp:Fraction.cpp
#include "Fraction.h"

#include <utility>

long long Fraction::gcd(long long a, long long b)
{
	a = abs(a);
	b = abs(b);
	if (a < b) std::swap(a, b);

	long long tmp;
	while (b != 0) {
		tmp = b;
		b = a % b;
		a = tmp;
	}

	return a;
}
long long Fraction::lcm(long long a, long long b)
{
	a = abs(a);
	b = abs(b);
	if (a > b) std::swap(a, b);

	if (a == 1) return b;

	long long i = a;
	while (i % b != 0)
	{
		i += a;
	}
	return i;
}

Fraction::Fraction()
{
	set(0, 1);
}
Fraction::Fraction(long long n)
{
	set(n, 1);
}
Fraction::Fraction(long long numer, long long denom)
{
	set(numer, denom);
}
Fraction::Fraction(const Fraction& b)
{
	set(b);
}

void Fraction::set(long long numer, long long denom)
{
	this->numer = numer;
	this->denom = denom;
	normal();
}
void Fraction::set(const Fraction& b)
{
	this->numer = b.numer;
	this->denom = b.denom;
}
void Fraction::setNumer(long long numer)
{
	this->numer = numer;
	normal();
}
void Fraction::setDenom(long long denom)
{
	this->denom = denom;
	normal();
}

inline long long Fraction::getNumer()
{
	return numer;
}
inline long long Fraction::getDenom()
{
	return denom;
}

void Fraction::normal()
{
	long long gcd = this->gcd(getNumer(), getDenom());

	if (gcd == 1)
	{
		// 分母は常に正
		if (denom < 0)
		{
			numer *= -1;
			denom *= -1;
		}

		return;
	}

	long long numer = getNumer() / gcd;
	long long denom = getDenom() / gcd;

	// 分母は常に正
	if (denom < 0)
	{
		numer *= -1;
		denom *= -1;
	}

	set(numer, denom);
}

std::string Fraction::toString()
{
	std::string str = "";

	if (getDenom() == 1)
		str = std::to_string(getNumer());
	else
		str = std::to_string(getNumer()) + "/" + std::to_string(getDenom());

	return str;
}
long double Fraction::toLongDouble()
{
	return (long double)getNumer() / getDenom();
}

bool Fraction::equals(const Fraction& b) const {
	return numer == b.numer && denom == b.denom;
}
long long Fraction::compare(const Fraction& b) const  {
	long long lcm = this->lcm(denom, b.denom);

	return (lcm / denom) * numer - (lcm / b.denom) * b.numer;
}

const bool operator==(const Fraction& a, const Fraction& b) { return  a.equals(b); }
const bool operator!=(const Fraction& a, const Fraction& b) { return !a.equals(b); }
const bool operator>=(const Fraction& a, const Fraction& b) { return a.compare(b) >= 0; }
const bool operator<=(const Fraction& a, const Fraction& b) { return a.compare(b) <= 0; }
const bool operator>(const Fraction& a, const Fraction& b) { return a.compare(b) > 0; }
const bool operator<(const Fraction& a, const Fraction& b) { return a.compare(b) < 0; }

Fraction& Fraction::operator=(const Fraction& b) {
	this->set(b);

	return *this;
}

const Fraction operator+(const Fraction& a, const Fraction& b) {
	long long lcm = Fraction::lcm(a.denom, b.denom);
	long long numer = a.numer * (lcm / a.denom) + b.numer * (lcm / b.denom);

	return Fraction(numer, lcm);
}
const Fraction operator-(const Fraction& a, const Fraction& b) {
	return operator+(a, Fraction(-b.numer, b.denom));
}
const Fraction operator*(const Fraction& a, const Fraction& b) {
	long long gcd = Fraction::gcd(a.numer, b.denom);
	long long numer = a.numer / gcd;
	long long denom = b.denom / gcd;

	gcd = Fraction::gcd(b.numer, a.denom);
	numer *= b.numer / gcd;
	denom *= a.denom / gcd;

	return Fraction(numer, denom);
}
const Fraction operator/(const Fraction& a, const Fraction& b) {
	return operator*(a, Fraction(b.denom, b.numer));
}

Fraction& Fraction::operator+=(const Fraction& b) { return *this = *this + b; }
Fraction& Fraction::operator-=(const Fraction& b) { return *this = *this - b; }
Fraction& Fraction::operator*=(const Fraction& b) { return *this = *this * b; }
Fraction& Fraction::operator/=(const Fraction& b) { return *this = *this / b; }

Fraction Fraction::operator+() { return Fraction(this->numer, this->denom); };
Fraction Fraction::operator-() { return Fraction(-(this->numer), this->denom); };

Fraction& Fraction::operator++() { return *this += 1; }
Fraction& Fraction::operator--() { return *this += -1; }
Fraction Fraction::operator++(int) {
	Fraction tmp = *this;
	*this += 1;
	return tmp;
}
Fraction Fraction::operator--(int) {
	Fraction tmp = *this;
	*this += -1;
	return tmp;
}
```