前の記事で、C++で分数classを作ったのですが(https://qiita.com/HitsujiRere/items/43a4b53c64b8eec3b7bd )、C#でも書いてみようと思ったので書きました
前記事(C++編)の参考
- http://blog.livedoor.jp/add20/archives/2285655.html
- http://www002.upp.so-net.ne.jp/ys_oota/effec/chapter4.htm
コードは下記(# コード)
内容
コメントを書き忘れたのですが、C++の記事とほぼ同じですし、大体はコードを読んでもらえるとわかると思います
※numerは分子、denomは分母を表しています
あと、ToString()や四則演算,等号不等号,キャストを実装してありますので、使い物にはなると思います
感想
C++やC#、どちらも良いところがあるなと感じた
C++ではlong→Fractionのキャストを書かなくても、インスタンスから自動的に変換してくれる(みたいだ
C#ではメソッドなどがかなり書きやすいと感じた(慣れもあるかもしれない
コード
コードはこちら
VS19で書いたのでnamespaceがありますが、そこを適当に変えるor削除するなどお願います
using System;
namespace Fraction_cs
{
class Fraction
{
public long numer { get; private set; }
public long denom { get; private set; }
public Fraction(long numer = 0)
{
this.numer = numer;
this.denom = 1;
}
public Fraction(long numer, long denom)
{
this.numer = numer;
this.denom = denom;
Normal();
}
public Fraction(Fraction b)
{
this.numer = b.numer;
this.denom = b.denom;
}
static void Swap<T>(ref T a, ref T b)
{
var tmp = a;
a = b;
b = tmp;
}
static long GCD(long a, long b)
{
a = Math.Abs(a);
b = Math.Abs(b);
if (a < b) Swap(ref a, ref b);
if (a == 1) return b;
var tmp = a;
while (b != 0)
{
tmp = b;
b = a % b;
a = tmp;
}
return tmp;
}
static long LCM(long a, long b)
{
a = Math.Abs(a);
b = Math.Abs(b);
if (a > b) Swap(ref a, ref b);
if (a == 1) return b;
var tmp = a;
while (tmp % b != 0)
{
tmp += a;
}
return tmp;
}
void Normal()
{
var gcd = GCD(numer, denom);
numer /= gcd;
denom /= gcd;
if (denom < 0)
{
numer *= -1;
denom *= -1;
}
}
public override string ToString()
{
if (denom == 1)
{
return numer.ToString();
}
else
{
return numer + "/" + denom;
}
}
public override bool Equals(object b)
{
if (b is Fraction b2 &&
this.numer == b2.numer &&
this.denom == b2.denom)
{
return true;
}
return false;
}
public static long Compare(Fraction a, Fraction b)
{
var lcm = LCM(a.denom, b.denom);
return (lcm / a.denom) * a.numer - (lcm / b.denom) * b.numer;
}
public static bool operator ==(Fraction a, Fraction b)
{
return a.Equals(b);
}
public static bool operator !=(Fraction a, Fraction b)
{
return !a.Equals(b);
}
public static bool operator >=(Fraction a, Fraction b)
{
return Compare(a, b) >= 0;
}
public static bool operator >(Fraction a, Fraction b)
{
return Compare(a, b) > 0;
}
public static bool operator <=(Fraction a, Fraction b)
{
return Compare(a, b) <= 0;
}
public static bool operator <(Fraction a, Fraction b)
{
return Compare(a, b) < 0;
}
public static Fraction operator +(Fraction a, Fraction b)
{
var lcm = LCM(a.denom, b.denom);
var numer = a.numer * (lcm / a.denom) + b.numer * (lcm / b.denom);
return new Fraction(numer, lcm);
}
public static Fraction operator -(Fraction a, Fraction b)
{
var lcm = LCM(a.denom, b.denom);
var numer = a.numer * (lcm / a.denom) - b.numer * (lcm / b.denom);
return new Fraction(numer, lcm);
}
public static Fraction operator *(Fraction a, Fraction b)
{
var gcd = GCD(a.numer, b.denom);
var numer = a.numer / gcd;
var denom = b.denom / gcd;
gcd = GCD(b.numer, a.denom);
numer *= b.numer / gcd;
denom *= a.denom / gcd;
return new Fraction(numer, denom);
}
public static Fraction operator /(Fraction a, Fraction b)
{
var gcd = GCD(a.numer, b.numer);
var numer = a.numer / gcd;
var denom = b.numer / gcd;
gcd = GCD(b.denom, a.denom);
numer *= b.denom / gcd;
denom *= a.denom / gcd;
return new Fraction(numer, denom);
}
public static Fraction operator +(Fraction a)
{
return new Fraction(a);
}
public static Fraction operator -(Fraction a)
{
var b = new Fraction(a);
b.numer *= -1;
return b;
}
public static Fraction operator ++(Fraction a)
{
a.numer++;
a.Normal();
return new Fraction(a);
}
public static Fraction operator --(Fraction a)
{
a.numer--;
a.Normal();
return new Fraction(a);
}
public static implicit operator Fraction(long a)
{
return new Fraction(a);
}
public static explicit operator double(Fraction a)
{
return (double)a.numer / (double)a.denom;
}
}
}