Imaginary base numbers: Difference between revisions
Content added Content deleted
(Added Sidef) |
|||
Line 302: | Line 302: | ||
</tr> |
</tr> |
||
</table> |
</table> |
||
=={{header|Kotlin}}== |
|||
The following deals with conversions to and from quater-imaginary only. |
|||
As the JDK lacks a complex number class, I've included a very basic one in the program. |
|||
<lang scala>// version 1.2.10 |
|||
import kotlin.math.ceil |
|||
class Complex(val real: Double, val imag: Double) { |
|||
constructor(r: Int, i: Int) : this(r.toDouble(), i.toDouble()) |
|||
operator fun plus(other: Complex) = Complex(real + other.real, imag + other.imag) |
|||
operator fun times(other: Complex) = Complex( |
|||
real * other.real - imag * other.imag, |
|||
real * other.imag + imag * other.real |
|||
) |
|||
operator fun times(other: Double) = Complex(real * other, imag * other) |
|||
fun inv(): Complex { |
|||
val denom = real * real + imag * imag |
|||
return Complex(real / denom, -imag / denom) |
|||
} |
|||
operator fun unaryMinus() = Complex(-real, -imag) |
|||
operator fun minus(other: Complex) = this + (-other) |
|||
operator fun div(other: Complex) = this * other.inv() |
|||
// only works properly if 'real' and 'imag' are both integral |
|||
fun toQuaterImaginary(): QuaterImaginary { |
|||
if (real == 0.0 && imag == 0.0) return QuaterImaginary("0") |
|||
var re = real.toInt() |
|||
var im = imag.toInt() |
|||
var fi = -1 |
|||
val sb = StringBuilder() |
|||
while (re != 0) { |
|||
var rem = re % -4 |
|||
re /= -4 |
|||
if (rem < 0) { |
|||
rem = 4 + rem |
|||
re++ |
|||
} |
|||
sb.append(rem) |
|||
sb.append(0) |
|||
} |
|||
if (im != 0) { |
|||
var f = (Complex(0.0, imag) / Complex(0.0, 2.0)).real |
|||
im = ceil(f).toInt() |
|||
f = -4.0 * (f - im.toDouble()) |
|||
var index = 1 |
|||
while (im != 0) { |
|||
var rem = im % -4 |
|||
im /= -4 |
|||
if (rem < 0) { |
|||
rem = 4 + rem |
|||
im++ |
|||
} |
|||
if (index < sb.length) { |
|||
sb[index] = (rem + 48).toChar() |
|||
} |
|||
else { |
|||
sb.append(0) |
|||
sb.append(rem) |
|||
} |
|||
index += 2 |
|||
} |
|||
fi = f.toInt() |
|||
} |
|||
sb.reverse() |
|||
if (fi != -1) sb.append(".$fi") |
|||
var s = sb.toString().trimStart('0') |
|||
if (s.startsWith(".")) s = "0$s" |
|||
return QuaterImaginary(s) |
|||
} |
|||
override fun toString(): String { |
|||
val real2 = if (real == -0.0) 0.0 else real // get rid of negative zero |
|||
val imag2 = if (imag == -0.0) 0.0 else imag // ditto |
|||
var result = if (imag2 >= 0.0) "$real2 + ${imag2}i" else "$real2 - ${-imag2}i" |
|||
result = result.replace(".0 ", " ").replace(".0i", "i").replace(" + 0i", "") |
|||
if (result.startsWith("0 + ")) result = result.drop(4) |
|||
if (result.startsWith("0 - ")) result = "-" + result.drop(4) |
|||
return result |
|||
} |
|||
} |
|||
class QuaterImaginary(val b2i: String) { |
|||
init { |
|||
if (b2i == "" || !b2i.all { it in "0123." } || b2i.count { it == '.'} > 1 ) |
|||
throw RuntimeException("Invalid Base 2i number") |
|||
} |
|||
fun toComplex(): Complex { |
|||
val pointPos = b2i.indexOf(".") |
|||
var posLen = if (pointPos != -1) pointPos else b2i.length |
|||
var sum = Complex(0.0, 0.0) |
|||
var prod = Complex(1.0, 0.0) |
|||
for (j in 0 until posLen) { |
|||
val k = (b2i[posLen - 1 - j] - '0').toDouble() |
|||
if (k > 0.0) sum += prod * k |
|||
prod *= twoI |
|||
} |
|||
if (pointPos != -1) { |
|||
prod = invTwoI |
|||
for (j in posLen + 1 until b2i.length) { |
|||
val k = (b2i[j] - '0').toDouble() |
|||
if (k > 0.0) sum += prod * k |
|||
prod *= invTwoI |
|||
} |
|||
} |
|||
return sum |
|||
} |
|||
override fun toString() = b2i |
|||
companion object { |
|||
val twoI = Complex(0.0, 2.0) |
|||
val invTwoI = twoI.inv() |
|||
} |
|||
} |
|||
fun main(args: Array<String>) { |
|||
val fmt = "%4s -> %8s -> %4s" |
|||
for (i in 1..16) { |
|||
var c1 = Complex(i, 0) |
|||
var qi = c1.toQuaterImaginary() |
|||
var c2 = qi.toComplex() |
|||
print("$fmt ".format(c1, qi, c2)) |
|||
c1 = -c1 |
|||
qi = c1.toQuaterImaginary() |
|||
c2 = qi.toComplex() |
|||
println(fmt.format(c1, qi, c2)) |
|||
} |
|||
println() |
|||
for (i in 1..16) { |
|||
var c1 = Complex(0, i) |
|||
var qi = c1.toQuaterImaginary() |
|||
var c2 = qi.toComplex() |
|||
print("$fmt ".format(c1, qi, c2)) |
|||
c1 = -c1 |
|||
qi = c1.toQuaterImaginary() |
|||
c2 = qi.toComplex() |
|||
println(fmt.format(c1, qi, c2)) |
|||
} |
|||
}</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|Perl 6}}== |
=={{header|Perl 6}}== |