floating-point arithmetic의 오차 때문에, 누적시킬수록 오차가 커지는 문제를 해결하기 위하여 작성해 보았습니다. Value-type이므로 편하게 쓰시면 됩니다.
struct Fraction
{
private int numerator;
private int denominator;
public int Numerator { get { return numerator; } }
public int Denominator { get { return denominator; } }
public Fraction(int num) : this()
{
this.SetValue(num);
}
public Fraction(int numerator, int denominator) : this()
{
this.SetValue(numerator, denominator);
}
// note that the change is irreversible.
public static implicit operator float(Fraction f)
{
return (float)f.numerator / f.denominator;
}
public static implicit operator double(Fraction f)
{
return (double)f.numerator / f.denominator;
}
public static implicit operator Fraction(int i)
{
return new Fraction(i);
}
public static Fraction operator +(Fraction a, Fraction b)
{
return new Fraction(
a.numerator * b.denominator + b.numerator * a.denominator,
a.denominator * b.denominator);
}
public static Fraction operator -(Fraction a, Fraction b)
{
return new Fraction(
a.numerator * b.denominator - b.numerator * a.denominator,
a.denominator * b.denominator);
}
public static Fraction operator *(Fraction a, Fraction b)
{
return new Fraction(
a.numerator * b.numerator,
a.denominator * b.denominator);
}
public static Fraction operator /(Fraction a, Fraction b)
{
return new Fraction(
a.numerator * b.denominator,
a.denominator * b.numerator);
}
public void SetValue(int num)
{
this.numerator = num;
this.denominator = 1;
}
public void SetValue(int numerator, int denominator)
{
this.numerator = numerator;
this.denominator = denominator;
Reduce();
}
private void Reduce()
{
// get GCD with Euclidean algorithm
int a = Math.Abs(this.numerator);
int b = Math.Abs(this.denominator);
int temp;
while (b != 0)
{
temp = a % b;
a = b;
b = temp;
}
this.numerator /= a;
this.denominator /= a;
}
public Fraction Reciprocal()
{
return new Fraction(denominator, numerator);
}
public override string ToString()
{
double value = this;
if (value == (int)value)
return ""+value;
return numerator+"/"+denominator;
}

댓글을 달아 주세요