Imaginary base numbers: Difference between revisions

(Added Wren)
Line 2,452:
15i -> 102000.2 -> 15i -15i -> 2010.2 -> -15i
16i -> 102000.0 -> 16i -16i -> 2000.0 -> -16i</pre>
 
=={{header|Nim}}==
{{trans|Kotlin}}
This is a fairly faithful translation of the Kotlin program except that we had not to define a Complex type as Nim provides the module “complex” in its standard library. We had only to define a function “toString” for the “Complex[float]” type, function to use in place of “$” in order to get a more pleasant output.
<lang Nim>import algorithm, complex, math, strformat, strutils
 
const
TwoI = complex(0.0, 2.0)
InvTwoI = inv(TwoI)
 
type QuaterImaginery = object
b2i: string
 
# Conversions between digit character and digit value.
template digitChar(n: range[0..9]): range['0'..'9'] = chr(n + ord('0'))
template digitValue(c: range['0'..'9']): range[0..9] = ord(c) - ord('0')
 
 
####################################################################################################
# Quater imaginary functions.
 
func initQuaterImaginary(s: string): QuaterImaginery =
## Create a Quater imaginary number.
if s.len == 0 or not s.allCharsInSet({'0'..'3', '.'}) or s.count('.') > 1:
raise newException(ValueError, "invalid base 2i number.")
result = QuaterImaginery(b2i: s)
 
#---------------------------------------------------------------------------------------------------
 
func toComplex(q: QuaterImaginery): Complex[float] =
## Convert a Quater imaginary number to a complex.
 
let pointPos = q.b2i.find('.')
let posLen = if pointPos != -1: pointPos else: q.b2i.len
var prod = complex(1.0)
 
for j in 0..<posLen:
let k = float(q.b2i[posLen - 1 - j].digitValue)
if k > 0: result += prod * k
prod *= TwoI
 
if pointPos != -1:
prod = InvTwoI
for j in (posLen + 1)..q.b2i.high:
let k = float(q.b2i[j].digitValue)
if k > 0: result += prod * k
prod *= InvTwoI
 
#---------------------------------------------------------------------------------------------------
 
func `$`(q: QuaterImaginery): string =
## Convert a Quater imaginary number to a string.
q.b2i
 
 
####################################################################################################
# Supplementary functions for complex numbers.
 
func toQuaterImaginary(c: Complex): QuaterImaginery =
## Convert a complex number to a Quater imaginary number.
 
if c.re == 0 and c.im == 0: return initQuaterImaginary("0")
 
var re = c.re.toInt
var im = c.im.toInt
var fi = -1
 
while re != 0:
var rem = re mod -4
re = re div -4
if rem < 0:
inc rem, 4
inc re
result.b2i.add rem.digitChar
result.b2i.add '0'
 
if im != 0:
var f = (complex(0.0, c.im) / TwoI).re
im = f.ceil.toInt
f = -4 * (f - im.toFloat)
var index = 1
while im != 0:
var rem = im mod -4
im = im div -4
if rem < 0:
inc rem, 4
inc im
if index < result.b2i.len:
result.b2i[index] = rem.digitChar
else:
result.b2i.add '0'
result.b2i.add rem.digitChar
inc index, 2
fi = f.toInt
 
result.b2i.reverse()
if fi != -1: result.b2i.add "." & $fi
result.b2i = result.b2i.strip(leading = true, trailing = false, {'0'})
if result.b2i.startsWith('.'): result.b2i = '0' & result.b2i
 
#---------------------------------------------------------------------------------------------------
 
func toString(c: Complex[float]): string =
## Convert a complex number to a string.
## This function is used in place of `$`.
 
let real = if c.re.classify == fcNegZero: 0.0 else: c.re
let imag = if c.im.classify == fcNegZero: 0.0 else: c.im
result = if imag >= 0: fmt"{real} + {imag}i" else: fmt"{real} - {-imag}i"
result = result.replace(".0 ", " ").replace(".0i", "i").replace(" + 0i", "")
if result.startsWith("0 + "): result = result[4..^1]
if result.startsWith("0 - "): result = '-' & result[4..^1]
 
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
when isMainModule:
 
for i in 1..16:
var c1 = complex(i.toFloat)
var qi = c1.toQuaterImaginary
var c2 = qi.toComplex
stdout.write fmt"{c1.toString:>4s} → {qi:>8s} → {c2.toString:>4s} "
c1 = -c1
qi = c1.toQuaterImaginary
c2 = qi.toComplex
echo fmt"{c1.toString:>4s} → {qi:>8s} → {c2.toString:>4s}"
 
echo ""
 
for i in 1..16:
var c1 = complex(0.0, i.toFloat)
var qi = c1.toQuaterImaginary
var c2 = qi.toComplex
stdout.write fmt"{c1.toString:>4s} → {qi:>8s} → {c2.toString:>4s} "
c1 = -c1
qi = c1.toQuaterImaginary
c2 = qi.toComplex
echo fmt"{c1.toString:>4s} → {qi:>8s} → {c2.toString:>4s}"</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}}==
Anonymous user