Imaginary base numbers: Difference between revisions

Content added Content deleted
m (→‎{{header|Perl 6}}: fix slightly too aggressive rounding)
(Added Java)
Line 489: Line 489:
15 -> 102000.2 -> 16 -15 -> 2010.2 -> -14
15 -> 102000.2 -> 16 -15 -> 2010.2 -> -14
16 -> 102000.0 -> 16 -16 -> 2000.0 -> -16</pre>
16 -> 102000.0 -> 16 -16 -> 2000.0 -> -16</pre>

=={{header|Java}}==
{{trans|Kotlin}}
<lang Java>public class ImaginaryBaseNumber {
private static class Complex {
private Double real, imag;

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

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

public Complex add(Complex rhs) {
return new Complex(
real + rhs.real,
imag + rhs.imag
);
}

public Complex times(Complex rhs) {
return new Complex(
real * rhs.real - imag * rhs.imag,
real * rhs.imag + imag * rhs.real
);
}

public Complex times(double rhs) {
return new Complex(
real * rhs,
imag * rhs
);
}

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

public Complex unaryMinus() {
return new Complex(-real, -imag);
}

public Complex divide(Complex rhs) {
return this.times(rhs.inv());
}

// only works properly if 'real' and 'imag' are both integral
public QuaterImaginary toQuaterImaginary() {
if (real == 0.0 && imag == 0.0) return new QuaterImaginary("0");
int re = real.intValue();
int im = imag.intValue();
int fi = -1;
StringBuilder sb = new StringBuilder();
while (re != 0) {
int rem = re % -4;
re /= -4;
if (rem < 0) {
rem += 4;
re++;
}
sb.append(rem);
sb.append(0);
}
if (im != 0) {
Double f = new Complex(0.0, imag).divide(new Complex(0.0, 2.0)).real;
im = ((Double) Math.ceil(f)).intValue();
f = -4.0 * (f - im);
int index = 1;
while (im != 0) {
int rem = im % -4;
im /= -4;
if (rem < 0) {
rem += 4;
im++;
}
if (index < sb.length()) {
sb.setCharAt(index, (char) (rem + 48));
} else {
sb.append(0);
sb.append(rem);
}
index += 2;
}
fi = f.intValue();
}
sb.reverse();
if (fi != -1) sb.append(".").append(fi);
while (sb.charAt(0) == '0') sb.deleteCharAt(0);
if (sb.charAt(0) == '.') sb.insert(0, '0');
return new QuaterImaginary(sb.toString());
}

@Override
public String toString() {
double real2 = real == -0.0 ? 0.0 : real; // get rid of negative zero
double imag2 = imag == -0.0 ? 0.0 : imag; // ditto
String result = imag2 >= 0.0 ? String.format("%.0f + %.0fi", real2, imag2) : String.format("%.0f - %.0fi", real2, -imag2);
result = result.replace(".0 ", " ").replace(".0i", "i").replace(" + 0i", "");
if (result.startsWith("0 + ")) result = result.substring(4);
if (result.startsWith("0 - ")) result = result.substring(4);
return result;
}
}

private static class QuaterImaginary {
private static final Complex TWOI = new Complex(0.0, 2.0);
private static final Complex INVTWOI = TWOI.inv();

private String b2i;

public QuaterImaginary(String b2i) {
if (b2i.equals("") || !b2i.chars().allMatch(c -> "0123.".indexOf(c) > -1) || b2i.chars().filter(c -> c == '.').count() > 1) {
throw new RuntimeException("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);
Complex prod = new Complex(1, 0);

for (int j = 0; j < posLen; ++j) {
double k = b2i.charAt(posLen - 1 - j) - '0';
if (k > 0.0) sum = sum.add(prod.times(k));
prod = prod.times(TWOI);
}
if (pointPos != -1) {
prod = INVTWOI;
for (int j = posLen + 1; j < b2i.length(); ++j) {
double k = b2i.charAt(j) - '0';
if (k > 0.0) sum = sum.add(prod.times(k));
prod = prod.times(INVTWOI);
}
}

return sum;
}

@Override
public String toString() {
return b2i;
}
}

public static void main(String[] args) {
String fmt = "%4s -> %8s -> %4s";
for (int i = 1; i <= 16; ++i) {
Complex c1 = new Complex(i, 0);
QuaterImaginary qi = c1.toQuaterImaginary();
Complex c2 = qi.toComplex();
System.out.printf(fmt + " ", c1, qi, c2);
c1 = c2.unaryMinus();
qi = c1.toQuaterImaginary();
c2 = qi.toComplex();
System.out.printf(fmt, c1, qi, c2);
System.out.println();
}
System.out.println();
for (int i = 1; i <= 16; ++i) {
Complex c1 = new Complex(0, i);
QuaterImaginary qi = c1.toQuaterImaginary();
Complex c2 = qi.toComplex();
System.out.printf(fmt + " ", c1, qi, c2);
c1 = c2.unaryMinus();
qi = c1.toQuaterImaginary();
c2 = qi.toComplex();
System.out.printf(fmt, c1, qi, c2);
System.out.println();
}
}
}</lang>
{{out}}
<pre> 1 -> 1 -> 1 -1 -> 103 -> -1
2 -> 2 -> 2 -2 -> 102 -> -2
3 -> 3 -> 3 -3 -> 101 -> -3
4 -> 10300 -> 4 -4 -> 100 -> -4
5 -> 10301 -> 5 -5 -> 203 -> -5
6 -> 10302 -> 6 -6 -> 202 -> -6
7 -> 10303 -> 7 -7 -> 201 -> -7
8 -> 10200 -> 8 -8 -> 200 -> -8
9 -> 10201 -> 9 -9 -> 303 -> -9
10 -> 10202 -> 10 -10 -> 302 -> -10
11 -> 10203 -> 11 -11 -> 301 -> -11
12 -> 10100 -> 12 -12 -> 300 -> -12
13 -> 10101 -> 13 -13 -> 1030003 -> -13
14 -> 10102 -> 14 -14 -> 1030002 -> -14
15 -> 10103 -> 15 -15 -> 1030001 -> -15
16 -> 10000 -> 16 -16 -> 1030000 -> -16

1i -> 10.2 -> 1i 1i -> 0.2 -> 1i
2i -> 10.0 -> 2i 2i -> 1030.0 -> 2i
3i -> 20.2 -> 3i 3i -> 1030.2 -> 3i
4i -> 20.0 -> 4i 4i -> 1020.0 -> 4i
5i -> 30.2 -> 5i 5i -> 1020.2 -> 5i
6i -> 30.0 -> 6i 6i -> 1010.0 -> 6i
7i -> 103000.2 -> 7i 7i -> 1010.2 -> 7i
8i -> 103000.0 -> 8i 8i -> 1000.0 -> 8i
9i -> 103010.2 -> 9i 9i -> 1000.2 -> 9i
10i -> 103010.0 -> 10i 10i -> 2030.0 -> 10i
11i -> 103020.2 -> 11i 11i -> 2030.2 -> 11i
12i -> 103020.0 -> 12i 12i -> 2020.0 -> 12i
13i -> 103030.2 -> 13i 13i -> 2020.2 -> 13i
14i -> 103030.0 -> 14i 14i -> 2010.0 -> 14i
15i -> 102000.2 -> 15i 15i -> 2010.2 -> 15i
16i -> 102000.0 -> 16i 16i -> 2000.0 -> 16i</pre>


=={{header|Kotlin}}==
=={{header|Kotlin}}==