A   complex number   is a number which can be written as:




a
+
b
×
i


{\displaystyle a+b\times i}


(sometimes shown as:




b
+
a
×
i


{\displaystyle b+a\times i}


where   



a


{\displaystyle a}

   and   



b


{\displaystyle b}

  are real numbers,   and   



i


{\displaystyle i}

   is   √ -1 



Typically, complex numbers are represented as a pair of real numbers called the "imaginary part" and "real part",   where the imaginary part is the number to be multiplied by 



i


{\displaystyle i}

.



Task

 Show addition, multiplication, negation, and inversion of complex numbers in separate functions. (Subtraction and division operations can be made with pairs of these operations.) 
 Print the results for each operation tested.
 Optional: Show complex conjugation.


By definition, the   complex conjugate   of




a
+
b
i


{\displaystyle a+bi}


is




a
−
b
i


{\displaystyle a-bi}





Some languages have complex number libraries available.   If your language does, show the operations.   If your language does not, also show the definition of this type.




class Complex {
    final Number real, imag
 
    static final Complex i = [0,1] as Complex
 
    Complex(Number r, Number i = 0) { (real, imag) = [r, i] }
 
    Complex(Map that) { (real, imag) = [that.real ?: 0, that.imag ?: 0] }
 
    Complex plus (Complex c) { [real + c.real, imag + c.imag] as Complex }
    Complex plus (Number n) { [real + n, imag] as Complex }
 
    Complex minus (Complex c) { [real - c.real, imag - c.imag] as Complex }
    Complex minus (Number n) { [real - n, imag] as Complex }
 
    Complex multiply (Complex c) { [real*c.real - imag*c.imag , imag*c.real + real*c.imag] as Complex }
    Complex multiply (Number n) { [real*n , imag*n] as Complex }
 
    Complex div (Complex c) { this * c.recip() }
    Complex div (Number n) { this * (1/n) }
 
    Complex negative () { [-real, -imag] as Complex }
 
    /** the complex conjugate of this complex number. Overloads the bitwise complement (~) operator. */
    Complex bitwiseNegate () { [real, -imag] as Complex }
 
    /** the magnitude of this complex number. */
    // could also use Math.sqrt( (this * (~this)).real )
    Number getAbs() { Math.sqrt( real*real + imag*imag ) }
    /** the magnitude of this complex number. */
    Number abs() { this.abs }
 
    /** the reciprocal of this complex number. */
    Complex getRecip() { (~this) / (ρ**2) }
    /** the reciprocal of this complex number. */
    Complex recip() { this.recip }
 
    /** derived polar angle θ (theta) for polar form. Normalized to 0 ≤ θ < 2π. */
    Number getTheta() {
        def θ = Math.atan2(imag,real)
        θ = θ < 0 ? θ + 2 * Math.PI : θ
    }
    /** derived polar angle θ (theta) for polar form. Normalized to 0 ≤ θ < 2π. */
    Number getΘ() { this.theta } // this is greek uppercase theta
 
    /** derived polar magnitude ρ (rho) for polar form. */
    Number getRho() { this.abs }
    /** derived polar magnitude ρ (rho) for polar form. */
    Number getΡ() { this.abs } // this is greek uppercase rho, not roman P
 
    /** Runs Euler's polar-to-Cartesian complex conversion,
     * converting [ρ, θ] inputs into a [real, imag]-based complex number */
    static Complex fromPolar(Number ρ, Number θ) {
        [ρ * Math.cos(θ), ρ * Math.sin(θ)] as Complex
    }
 
    /** Creates new complex with same magnitude ρ, but different angle θ */
    Complex withTheta(Number θ) { fromPolar(this.rho, θ) }
    /** Creates new complex with same magnitude ρ, but different angle θ */
    Complex withΘ(Number θ) { fromPolar(this.rho, θ) }
 
    /** Creates new complex with same angle θ, but different magnitude ρ */
    Complex withRho(Number ρ) { fromPolar(ρ, this.θ) }
    /** Creates new complex with same angle θ, but different magnitude ρ */
    Complex withΡ(Number ρ) { fromPolar(ρ, this.θ) } // this is greek uppercase rho, not roman P
 
    static Complex exp(Complex c) { fromPolar(Math.exp(c.real), c.imag) }
 
    static Complex log(Complex c) { [Math.log(c.rho), c.theta] as Complex }
 
    Complex power(Complex c) {
        def zero = [0] as Complex
        (this == zero && c != zero)  \
                ?  zero  \
                :  c == 1  \
                        ?  this  \
                        :  exp( log(this) * c )
    }
 
    Complex power(Number n) { this ** ([n, 0] as Complex) }
 
    boolean equals(that) {
        that != null && (that instanceof Complex \
                                ? [this.real, this.imag] == [that.real, that.imag] \
                                : that instanceof Number && [this.real, this.imag] == [that, 0])
    }
 
    int hashCode() { [real, imag].hashCode() }
 
    String toString() {
        def realPart = "${real}"
        def imagPart = imag.abs() == 1 ? "i" : "${imag.abs()}i"
        real == 0 && imag == 0 \
                ? "0" \
                : real == 0 \
                        ? (imag > 0 ? '' : "-")  + imagPart \
                        : imag == 0 \
                                ? realPart \
                                : realPart + (imag > 0 ? " + " : " - ")  + imagPart
    }
}