Task: Imaginary base numbers



C#: using System;
using System.Linq;
using System.Text;

namespace ImaginaryBaseNumbers {
    class Complex {
        private double real, imag;

        public Complex(int r, int i) {
            real = r;
            imag = i;
        }

        public Complex(double r, double i) {
            real = r;
            imag = i;
        }

        public static Complex operator -(Complex self) =>
            new Complex(-self.real, -self.imag);

        public static Complex operator +(Complex rhs, Complex lhs) =>
            new Complex(rhs.real + lhs.real, rhs.imag + lhs.imag);

        public static Complex operator -(Complex rhs, Complex lhs) =>
            new Complex(rhs.real - lhs.real, rhs.imag - lhs.imag);

        public static Complex operator *(Complex rhs, Complex lhs) =>
            new Complex(
                rhs.real * lhs.real - rhs.imag * lhs.imag,
                rhs.real * lhs.imag + rhs.imag * lhs.real
                );

        public static Complex operator *(Complex rhs, double lhs) =>
             new Complex(rhs.real * lhs, rhs.imag * lhs);

        public static Complex operator /(Complex rhs, Complex lhs) =>
            rhs * lhs.Inv();

        public Complex Inv() {
            double denom = real * real + imag * imag;
            return new Complex(real / denom, -imag / denom);
        }

        public QuaterImaginary ToQuaterImaginary() {
            if (real == 0.0 && imag == 0.0) return new QuaterImaginary("0");
            int re = (int)real;
            int im = (int)imag;
            int fi = -1;
            StringBuilder sb = new StringBuilder();
            while (re != 0) {
                int rem = re % -4;
                re /= -4;
                if (rem < 0) {
                    rem = 4 + rem;
                    re++;
                }
                sb.Append(rem);
                sb.Append(0);
            }
            if (im != 0) {
                double f = (new Complex(0.0, imag) / new Complex(0.0, 2.0)).real;
                im = (int)Math.Ceiling(f);
                f = -4.0 * (f - im);
                int index = 1;
                while (im != 0) {
                    int rem = im % -4;
                    im /= -4;
                    if (rem < 0) {
                        rem = 4 + rem;
                        im++;
                    }
                    if (index < sb.Length) {
                        sb[index] = (char)(rem + 48);
                    } else {
                        sb.Append(0);
                        sb.Append(rem);
                    }
                    index += 2;
                }
                fi = (int)f;
            }
            string reverse = new string(sb.ToString().Reverse().ToArray());
            sb.Length = 0;
            sb.Append(reverse);
            if (fi != -1) sb.AppendFormat(".{0}", fi);
            string s = sb.ToString().TrimStart('0');
            if (s[0] == '.') s = "0" + s;
            return new QuaterImaginary(s);
        }

        public override string ToString() {
            double real2 = (real == -0.0) ? 0.0 : real;  
            double imag2 = (imag == -0.0) ? 0.0 : imag;  
            if (imag2 == 0.0) {
                return string.Format("{0}", real2);
            }
            if (real2 == 0.0) {
                return string.Format("{0}i", imag2);
            }
            if (imag2 > 0.0) {
                return string.Format("{0} + {1}i", real2, imag2);
            }
            return string.Format("{0} - {1}i", real2, -imag2);
        }
    }

    class QuaterImaginary {
        internal static Complex twoI = new Complex(0.0, 2.0);
        internal static Complex invTwoI = twoI.Inv();

        private string b2i;

        public QuaterImaginary(string b2i) {
            if (b2i == "" || !b2i.All(c => "0123.".IndexOf(c) > -1) || b2i.Count(c => c == '.') > 1) {
                throw new Exception("Invalid Base 2i number");
            }
            this.b2i = b2i;
        }

        public Complex ToComplex() {
            int pointPos = b2i.IndexOf(".");
            int posLen = (pointPos != -1) ? pointPos : b2i.Length;
            Complex sum = new Complex(0.0, 0.0);
            Complex prod = new Complex(1.0, 0.0);
            for (int j = 0; j < posLen; j++) {
                double k = (b2i[posLen - 1 - j] - '0');
                if (k > 0.0) {
                    sum += prod * k;
                }
                prod *= twoI;
            }
            if (pointPos != -1) {
                prod = invTwoI;
                for (int j = posLen + 1; j < b2i.Length; j++) {
                    double k = (b2i[j] - '0');
                    if (k > 0.0) {
                        sum += prod * k;
                    }
                    prod *= invTwoI;
                }
            }

            return sum;
        }

        public override string ToString() {
            return b2i;
        }
    }

    class Program {
        static void Main(string[] args) {
            for (int i = 1; i <= 16; i++) {
                Complex c1 = new Complex(i, 0);
                QuaterImaginary qi = c1.ToQuaterImaginary();
                Complex c2 = qi.ToComplex();
                Console.Write("{0,4} -> {1,8} -> {2,4}     ", c1, qi, c2);
                c1 = -c1;
                qi = c1.ToQuaterImaginary();
                c2 = qi.ToComplex();
                Console.WriteLine("{0,4} -> {1,8} -> {2,4}", c1, qi, c2);
            }
            Console.WriteLine();
            for (int i = 1; i <= 16; i++) {
                Complex c1 = new Complex(0, i);
                QuaterImaginary qi = c1.ToQuaterImaginary();
                Complex c2 = qi.ToComplex();
                Console.Write("{0,4} -> {1,8} -> {2,4}     ", c1, qi, c2);
                c1 = -c1;
                qi = c1.ToQuaterImaginary();
                c2 = qi.ToComplex();
                Console.WriteLine("{0,4} -> {1,8} -> {2,4}", c1, qi, c2);
            }
        }
    }
}





Python: import math
import re

def inv(c):
    denom = c.real * c.real + c.imag * c.imag
    return complex(c.real / denom, -c.imag / denom)

class QuaterImaginary:
    twoI = complex(0, 2)
    invTwoI = inv(twoI)

    def __init__(self, str):
        if not re.match("^[0123.]+$", str) or str.count('.') > 1:
            raise Exception('Invalid base 2i number')
        self.b2i = str

    def toComplex(self):
        pointPos = self.b2i.find('.')
        posLen = len(self.b2i) if (pointPos < 0) else pointPos
        sum = complex(0, 0)
        prod = complex(1, 0)
        for j in xrange(0, posLen):
            k = int(self.b2i[posLen - 1 - j])
            if k > 0:
                sum += prod * k
            prod *= QuaterImaginary.twoI
        if pointPos != -1:
            prod = QuaterImaginary.invTwoI
            for j in xrange(posLen + 1, len(self.b2i)):
                k = int(self.b2i[j])
                if k > 0:
                    sum += prod * k
                prod *= QuaterImaginary.invTwoI
        return sum

    def __str__(self):
        return str(self.b2i)

def toQuaterImaginary(c):
    if c.real == 0.0 and c.imag == 0.0:
        return QuaterImaginary("0")

    re = int(c.real)
    im = int(c.imag)
    fi = -1
    ss = ""
    while re != 0:
        re, rem = divmod(re, -4)
        if rem < 0:
            rem += 4
            re += 1
        ss += str(rem) + '0'
    if im != 0:
        f = c.imag / 2
        im = int(math.ceil(f))
        f = -4 * (f - im)
        index = 1
        while im != 0:
            im, rem = divmod(im, -4)
            if rem < 0:
                rem += 4
                im += 1
            if index < len(ss):
                ss[index] = str(rem)
            else:
                ss += '0' + str(rem)
            index = index + 2
        fi = int(f)
    ss = ss[::-1]
    if fi != -1:
        ss += '.' + str(fi)
    ss = ss.lstrip('0')
    if ss[0] == '.':
        ss = '0' + ss
    return QuaterImaginary(ss)

for i in xrange(1,17):
    c1 = complex(i, 0)
    qi = toQuaterImaginary(c1)
    c2 = qi.toComplex()
    print "{0:8} -> {1:>8} -> {2:8}     ".format(c1, qi, c2),

    c1 = -c1
    qi = toQuaterImaginary(c1)
    c2 = qi.toComplex()
    print "{0:8} -> {1:>8} -> {2:8}".format(c1, qi, c2)
print

for i in xrange(1,17):
    c1 = complex(0, i)
    qi = toQuaterImaginary(c1)
    c2 = qi.toComplex()
    print "{0:8} -> {1:>8} -> {2:8}     ".format(c1, qi, c2),

    c1 = -c1
    qi = toQuaterImaginary(c1)
    c2 = qi.toComplex()
    print "{0:8} -> {1:>8} -> {2:8}".format(c1, qi, c2)

print "done"