177 lines
5.9 KiB
C#
177 lines
5.9 KiB
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; // get rid of negative zero
|
|
double imag2 = (imag == -0.0) ? 0.0 : imag; // ditto
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|