C#으로 복소수 구현

c-sharp

(HHS) #1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Complex
{
    class Complex
    {
        double real; // 실수부
        double imag; // 허수부

        public Complex() 
        {
            real = 0;
            imag = 0;
        }

        public Complex(double _real, double _imag)
        {
            real = _real;
            imag = _imag;
        }

        public Complex(double _imag)
        {
            real = 0;
            imag = _imag;
        }

        public Complex(Complex complex)
        {
            real = complex.real;
            imag = complex.imag;
        }

        public double Real 
        {
            get { return real; }
            set { real = value; }
        }
        public double Imag  
        {
            get { return imag; }
            set { imag = value; }
        }

        public const Complex ImaginaryUnit = new Complex(1);

        public double Abs()
        {
            return Math.Sqrt(real * real + imag * imag);
        }
        public double Arg()
        {
            return Math.Atan2(imag / real, 2.0 * Math.PI);
        }
        public Complex Conjugate() 
        {
            return new Complex(real, -imag);
        }

        public static Complex Sqrt(double value)
        {
            if(value < 0)
                return new Complex(Math.Sqrt(value));
            else
                return new Complex(Math.Sqrt(value), 0);
        }
        public static Complex Sqrt(Complex value)
        {

            double theta = value.Arg();
            double r = value.Abs();

            Complex z = new Complex(Math.Cos(theta/2), Math.Sin(theta/2));
            return r*z;
        }

        public static Complex Pow(double x, Complex y)
        {
            double a = Math.Pow(x, y.real);
            return new Complex(a*Math.Cos(y*Math.Log(x)), a*Math.Sin(y*Math.Log(x)));
        }
        public static Complex Pow(Complex x, double y)
        {
            double theta = x.Arg();
            double r = x.Abs();

            return new Complex(r*Math.Cos(theta*y), r*Math.Sin(theta*y));
        }

 
        public static bool operator ==(Complex left, Complex right)
        {
            return (left.real == right.real) && (left.imag == right.imag);
        }
        public static bool operator !=(Complex left, Complex right)
        {
            return (left.real != right.real) || (left.imag != right.imag);
        }
        public static bool operator ==(Complex left, double right)
        {
            return (left.real == right) && (left.imag == 0);
        }
        public static bool operator !=(Complex left, double right)
        {
            return (left.real != right) || (left != 0);
        }
        public static bool operator ==(double left, Complex right)
        {
            return (left == right.real) && (0 == right.imag);
        }
        public static bool operator !=(double left, Complex right)
        {
            return (left != right.real) || (0 != right.imag);
        }

        public static Complex operator +(Complex left, Complex right)
        {
            return new Complex(left.real + right.real, left.imag + right.imag);
        }
        public static Complex operator +(Complex left, double right)
        {
            return new Complex(left.real + right, left.imag);
        }
        public static Complex operator +(double left, Complex right)
        {
            return new Complex(left + right.real, right.imag);
        }
        public static Complex operator +(Complex z)
        {
            return new Complex(z.real, z.imag);
        }

        public static Complex operator -(Complex left, Complex right)
        {
            return new Complex(left.real - right.real, left.imag - right.imag);
        }
        public static Complex operator -(Complex left, double right)
        {
            return new Complex(left.real - right, left.imag);
        }
        public static Complex operator -(double left, Complex right)
        {
            return new Complex(left - right.real, right.imag);
        }
        public static Complex operator -(Complex z)
        {
            z.real *= -1;
            z.imag *= -1;
            return z;
        }

        public static Complex operator *(Complex left, Complex right)
        {
            return new Complex(left.real * right.real - left.imag * right.imag, left.real * right.imag + left.imag * right.real);
        }
        public static Complex operator *(Complex left, double right)
        {
            return new Complex(right * left.real, right * left.imag);
        }
        public static Complex operator *(double left, Complex right)
        {
            return new Complex(left * right.real, left * right.imag);
        }

        public static Complex operator /(Complex left, Complex right)
        {
            double t = right.real * right.real + right.imag * right.imag;

            if (right == 0)
                throw new System.DivideByZeroException();

            return new Complex((left.real * right.real + left.imag * right.imag) / t, (-left.real * right.imag + left.imag * right.real) / t);
        }
        public static Complex operator /(Complex left, double right)
        {
            if(right == 0)
                throw new System.DivideByZeroException();

            return new Complex(left.real / right, left.imag / right);
        }
        public static Complex operator /(double left, Complex right)
        {
            double t = right.real * right.real + right.imag * right.imag; ;

            if(right == 0)
                throw new System.DivideByZeroException();

            return new Complex((left * right.real) / t, -(left * right.imag) / t);
        }

        public override bool Equals(object obj)  { return this == (Complex)obj; }
        public override int GetHashCode() { return base.GetHashCode(); }
        public override string ToString()
        {
            if (this == 0)
                return "0";

            else if (imag == 0)
                return real.ToString();

            else if (real == 0)
                return imag + "i";

            else if (imag > 0)
                return real + "+" + imag + "i";
  
            else if(0 > imag)
                return real + (imag + "i"); 
        }
    }
}

(코드 이렇게 올리는게 맞을려나요…)

연산자 오버로딩은 물론이고,
편각, 켤레복소수, 절댓값, 복소수의 제곱근, 실수의 복소수 제곱, 복소수의 실수 제곱 등등…
생각나는 건 모조리 구현했습니다.

코린이가 짠 코드가 어떤지 평가 해주시면 감사하겠습니다.ㅠㅠ


(codesafer) #2

C# 은 조금밖에 안써봤지만, .Net 에 있는 Complex 를 상속받아 추가기능만 구현하는게
소스코드를 보는 사람도 아 이런게 추가되었구나 하기 쉽지 않을까요?
기본자료형을 상속받으면 출력 양식도 공유가능하고 말이죠.


(HHS) #3

.Net에 Complex가 있는지도 몰랐네요.ㅠㅠ
공부를 더 많이 해야 겠네요.


(crmerry) #4

연산자 오퍼레이팅은 넘나 귀찮다에요? 하나 해주면 다 해주고 싶다 말이에요?