(phixonline)--> with javascript_semantics include complex.e function base2(atom num, integer radix, precision = -8) if radix<-36 or radix>-2 then throw("radix out of range (-2..-36)") end if sequence result if num=0 then result = {"0",""} else integer place = 0 result = "" atom v = num atom upper_bound = 1/(1-radix), lower_bound = radix*upper_bound while not(lower_bound <= v) or not(v < upper_bound) do place += 1 v = num/power(radix,place) end while while (v or place > 0) and (place > precision) do integer digit = floor(radix*v - lower_bound) v = (radix*v - digit) if place=0 and not find('.',result) then result &= '.' end if result &= digit+iff(digit>9?'a'-10:'0') place -= 1 end while integer dot = find('.',result) if dot then result = trim_tail(result,'0') result = {result[1..dot-1],result[dot+1..$]} else result = {result,""} end if end if return result end function function zip(string a, string b) integer ld = length(a)-length(b) if ld!=0 then if ld>0 then b &= repeat('0',ld) else a &= repeat('0',abs(ld)) end if end if string res = "" for i=1 to length(a) do res &= a[i]&b[i] end for res = trim_tail(res,'0') if res="" then res = "0" end if return res end function function base(complexn num, integer radix, precision = -8) integer absrad = abs(radix), radix2 = -power(radix,2) if absrad<2 or absrad>6 then throw("base radix out of range") end if atom {re, im} = {complex_real(num), complex_imag(num)} string {re_wh, re_fr} = base2(re, radix2, precision), {im_wh, im_fr} = base2(im/radix, radix2, precision) string whole = reverse(zip(reverse(re_wh), reverse(im_wh))), fraction = zip(im_fr, re_fr) if fraction!="0" then whole &= '.'&fraction end if return whole end function function parse_base(string str, integer radix) complexn fraction = 0 integer dot = find('.',str) if dot then string fr = str[dot+1..$] for i=1 to length(fr) do integer c = fr[i] c -= iff(c>='a'?'a'-10:'0') fraction = complex_add(fraction,complex_mul(c,complex_power({0,radix},-i))) end for str = str[1..dot-1] end if str = reverse(str) for i=1 to length(str) do integer c = str[i] c -= iff(c>='a'?'a'-10:'0') fraction = complex_add(fraction,complex_mul(c,complex_power({0,radix},(i-1)))) end for return fraction end function constant tests = {{0,2},{1,2},{5,2},{-13,2},{{0,9},2},{{0,-3},2},{{7.75,-7.5}, 2},{.25, 2}, -- base 2i tests {{5,5}, 2},{{5,5}, 3},{{5,5}, 4},{{5,5}, 5},{{5,5}, 6}, -- same value, positive imaginary bases {{5,5},-2},{{5,5},-3},{{5,5},-4},{{5,5},-5},{{5,5},-6}, -- same value, negative imaginary bases {{227.65625,10.859375},4}, -- larger test value {{-579.8225308641975744,-5296.406378600824},6}} -- phix.rules -- matches output of Sidef and Raku: for t=1 to length(tests) do {complexn v, integer r} = tests[t] string ibase = base(v,r), strv = complex_sprint(v), strb = complex_sprint(parse_base(ibase, r)) printf(1,"base(%20s, %2di) = %-10s : parse_base(%12s, %2di) = %s\n", {strv, r, ibase, '"'&ibase&'"', r, strb}) end for -- matches output of Kotlin, Java, Go, D, and C#: for ri=1 to 2 do -- real then imag for i=1 to 16 do complexn c = iff(ri=1?i:{0,i}), nc = complex_neg(c) string sc = complex_sprint(c), snc = complex_sprint(nc), ib = base(c,2), inb = base(nc,2), rc = complex_sprint(parse_base(ib,2)), rnc = complex_sprint(parse_base(inb,2)) printf(1,"%4s -> %8s -> %4s %4s -> %8s -> %4s\n", {sc, ib, rc, snc, inb, rnc }) end for puts(1,"\n") end for