Imaginary base numbers: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) 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}}== |