Imaginary base numbers: Difference between revisions

Line 1,298:
15i -> 102000.2 -> 15i 15i -> 2010.2 -> 15i
16i -> 102000.0 -> 16i 16i -> 2000.0 -> 16i</pre>
 
=={{header|Julia||==
{{trans|C#}}
<lang julia>import Base.show, Base.parse
 
function inbase4(charvec::Vector)
if (!all(x -> x in ['-', '0', '1', '2', '3', '.'], charvec)) ||
((x = findlast(x -> x == '-', charvec)) != nothing && x > findfirst(x -> x != '-', charvec)) ||
((x = findall(x -> x == '.', charvec)) != nothing && length(x) > 1)
return false
end
true
end
inbase4(s::String) = inbase4(split(s, ""))
 
abstract type ImaginaryBaseNumber <: Number end
 
struct QuaterImaginary <: ImaginaryBaseNumber
cvector::Vector{Char}
isnegative::Bool
end
 
function QuaterImaginary(charvec::Vector{Char})
isneg = false
if !inbase4(charvec)
throw("Constructor vector for QuaterImaginary ($charvec) is not base 2i")
elseif (i = length(something(findall(x -> x == '-', charvec), []))) > 0
isneg = (-1) ^ i == -1
end
while length(charvec) > 1 && charvec[1] == '0' && charvec[2] != '.'
popfirst!(charvec)
end
if (i = findfirst(x -> x == '.', charvec)) != nothing
while length(charvec) > 3 && charvec[end] == '0' && charvec[end-1] != '.'
pop!(charvec)
end
end
if charvec[1] == '.'
pushfirst!(charvec, '0')
end
if charvec[end] == '.'
pop!(charvec)
end
QuaterImaginary(filter!(x -> x in ['0', '1', '2', '3', '.'], charvec), isneg)
end
 
function QuaterImaginary(s::String = "0")
if match(r"^-?[0123\.]+$", s) == nothing
throw("String constructor argument <$s> for QuaterImaginary is not base 2i")
end
QuaterImaginary([s[i] for i in 1:length(s)])
end
 
show(io::IO, qim::QuaterImaginary) = print(io, qim.isnegative ? "-" : "", join(qim.cvector, ""))
 
function parse(QuaterImaginary, x::Complex)
sb = Vector{Char}()
rea, ima = Int(floor(real(x))), Int(floor(imag(x)))
if floor(real(x)) != rea || floor(imag(x)) != ima
throw("Non-integer real and complex portions of complex numbers are not supported for QuaterImaginary")
elseif rea == 0 == ima
return QuaterImaginary(['0'])
else
fi = -1
while rea != 0
rea, rem = divrem(rea, -4)
if rem < 0
rem += 4
rea += 1
end
push!(sb, Char(rem + '0'), '0')
end
if ima != 0
f = real((ima * im)/(2im))
ima = Int(ceil(f))
f = -4.0 * (f - ima)
idx = 1
while ima != 0
ima, rem = divrem(ima, -4)
if rem < 0
rem += 4
ima += 1
end
if idx < length(sb)
sb[idx + 1] = Char(rem + '0')
else
push!(sb, '0', Char(rem + '0'))
end
idx += 2
end
fi = Int(floor(f))
end
sb = reverse(sb)
if fi != -1
push!(sb, '.')
append!(sb, map(x -> x[1], split(string(fi), "")))
end
end
QuaterImaginary(sb)
end
 
function parse(Complex, qim::QuaterImaginary)
pointpos = ((x = indexin('.', qim.cvector))[1] == nothing) ? -1 : x[1]
poslen = (pointpos != -1) ? pointpos : length(qim.cvector) + 1
qsum = 0.0 + 0.0im
prod = 1.0 + 0.0im
for j in 1:poslen-1
k = Float64(qim.cvector[poslen - j] - '0')
if k > 0.0
qsum += prod * k
end
prod *= 2im
end
if pointpos != -1
prod = inv(2im)
for j in poslen+1:length(qim.cvector)
k = Float64(qim.cvector[j] - '0')
if k > 0.0
qsum += prod * k
end
prod *= inv(2im)
end
end
qsum
end
 
function testquim()
function printcqc(c)
q = parse(QuaterImaginary, Complex(c))
c2 = parse(Complex, q)
if imag(c2) == 0
c2 = Int(c2)
end
print(lpad(c, 10), " -> ", lpad(q, 10), " -> ", lpad(c2, 12))
end
for i in 1:16
printcqc(i)
print(" ")
printcqc(-i)
println()
end
println()
for i in 1:16
c1 = Complex(0, i)
printcqc(c1)
print(" ")
printcqc(-c1)
println()
end
end
 
testquim()
</lang>{{output}}<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
 
0 + 1im -> 10.2 -> 0.0 + 1.0im 0 - 1im -> 0.2 -> 0.0 - 1.0im
0 + 2im -> 10.0 -> 0.0 + 2.0im 0 - 2im -> 1030.0 -> 0.0 - 2.0im
0 + 3im -> 20.2 -> 0.0 + 3.0im 0 - 3im -> 1030.2 -> 0.0 - 3.0im
0 + 4im -> 20.0 -> 0.0 + 4.0im 0 - 4im -> 1020.0 -> 0.0 - 4.0im
0 + 5im -> 30.2 -> 0.0 + 5.0im 0 - 5im -> 1020.2 -> 0.0 - 5.0im
0 + 6im -> 30.0 -> 0.0 + 6.0im 0 - 6im -> 1010.0 -> 0.0 - 6.0im
0 + 7im -> 103000.2 -> 0.0 + 7.0im 0 - 7im -> 1010.2 -> 0.0 - 7.0im
0 + 8im -> 103000.0 -> 0.0 + 8.0im 0 - 8im -> 1000.0 -> 0.0 - 8.0im
0 + 9im -> 103010.2 -> 0.0 + 9.0im 0 - 9im -> 1000.2 -> 0.0 - 9.0im
0 + 10im -> 103010.0 -> 0.0 + 10.0im 0 - 10im -> 2030.0 -> 0.0 - 10.0im
0 + 11im -> 103020.2 -> 0.0 + 11.0im 0 - 11im -> 2030.2 -> 0.0 - 11.0im
0 + 12im -> 103020.0 -> 0.0 + 12.0im 0 - 12im -> 2020.0 -> 0.0 - 12.0im
0 + 13im -> 103030.2 -> 0.0 + 13.0im 0 - 13im -> 2020.2 -> 0.0 - 13.0im
0 + 14im -> 103030.0 -> 0.0 + 14.0im 0 - 14im -> 2010.0 -> 0.0 - 14.0im
0 + 15im -> 102000.2 -> 0.0 + 15.0im 0 - 15im -> 2010.2 -> 0.0 - 15.0im
0 + 16im -> 102000.0 -> 0.0 + 16.0im 0 - 16im -> 2000.0 -> 0.0 - 16.0im
</pre>
 
=={{header|Kotlin}}==
4,103

edits