Generalised floating point multiplication: Difference between revisions

m
m (converted list to a table, removed Kudos.)
m (→‎{{header|Wren}}: Minor tidy)
 
(31 intermediate revisions by 5 users not shown)
Line 1:
{{Template:Draft task}}
Use the [[Generalised floating point addition]] template to implement generalised floating point multiplication for a
If possible, define ''multiplication'' for floating point numbers where the digits are stored in an arbitrary base. eg. the digits cab be stored as binary, decimal, [[wp:Binary-coded decimal|Binary-coded decimal]], or even [[wp:Balanced ternary|Balanced ternary]].
[[wp:Balanced ternary|Balanced ternary]] test case.
 
'''Test case details''':
Balanced ternary is a way of representing numbers. Unlike the prevailing binary representation, a balanced ternary "real" is in base 3, and each digit can have the values 1, 0, or −1. For example, decimal 11 = 3<sup>2</sup> + 3<sup>1</sup> − 3<sup>0</sup>, thus can be written as "++−", while 6 = 3<sup>2</sup> − 3<sup>1</sup> + 0 × 3<sup>0</sup>, i.e., "+−0" and for an actual real number 6⅓ the ''exact'' representation is 3<sup>2</sup> − 3<sup>1</sup> + 0 × 3<sup>0</sup> + 1 × 3<sup>-1</sup> i.e., "+−0.+"
 
For this task, implement balanced ternary representation of real numbers with the following:
 
'''Requirements'''
# Support arbitrary precision real numbers, both positive and negative;
# Provide ways to convert to and from text strings, using digits '+', '-' and '0' (unless you are already using strings to represent balanced ternary; but see requirement 5).
# Provide ways to convert to and from native integer and real type (unless, improbably, your platform's native integer type ''is'' balanced ternary). If your native integers can't support arbitrary length, overflows during conversion must be indicated.
# Provide ways to perform addition, negation and multiplication directly on balanced ternary integers; do ''not'' convert to native integers first.
# Make your implementation efficient, with a reasonable definition of "efficient" (and with a reasonable definition of "reasonable").
# The Template should successfully handle these multiplications in other bases. In particular [[wp:Septemvigesimal|Septemvigesimal]] and "Balanced base-27".
 
Optionally:
* For faster ''long'' multiplication use [[wp:Karatsuba_algorithm|Karatsuba algorithm]].
* Using the Karatsuba algorithm, spread the computation across multiple CPUs.
 
'''Test case 1''' - With balanced ternaries ''a'' from string "+-0++0+.+-0++0+", ''b'' from native real -436.436, ''c'' "+-++-.+-++-":
* write out ''a'', ''b'' and ''c'' in decimal notation.
* calculate ''a'' × (''b'' − ''c''), write out the result in both ternary and decimal notations.
* In the above limit the precision to 81 ternary digits after the point.
 
'''Test case 2''' - Generate a multiplication table of balanced ternaries where the rows of the table are for a 1st factor of 1 to 27, and the column of the table are for the second factor of 1 to 12.
 
Implement the code in a generalised form (such as a [[wp:Template (programming)|Template]], [[wp:Modular programming|Module]] or [[wp:Mixin|Mixin]] etc) that permits reusing of the code for different [[wp:Base_(exponentiation)#In_numeral_systems|Bases]].
Line 6 ⟶ 31:
If it is not possible to implement code in syntax of the specific language then:
* note the reason.
* perform the ''test case'' using a built-in or external library.
<!--
 
'''Test case:'''
 
Use the Template to define [[wp:Arbitrary-precision arithmetic|Arbitrary precision multiplication]] on numbers stored in BinaryBalanced Coded DecimalTernary.
 
{|class="wikitable" style="text-align: center; margin: 1em auto 1em auto;"
|+ Calculate the terms for -87 to 2021 in this sequence of calculations
|-
! Number !! Term calculation !! Result
|-
| -87 || 111111111e63**2 x 81 + 2e135 - 1e126 || 1e144
|-
| -76 || 111111111111111111e54**2 x 81 + 2e126 - 1e108 || 1e144
|-
| -65 || 111111111111111111111111111e45**2 x 81 + 2e117 - 1e90 || 1e144
|-
| -54 || 111111111111111111111111111111111111e36**2 x 81 + 2e108 - 1e72 || 1e144
|-
| etc. || The last calculation will be with floating point numbers of more then 500 digits || 1e144
|}
Note: The results will always be 1e144.
-->
 
The Template should successfully handle these multiplications in other bases.
=={{header|ALGOL 68}}==
{{works with|ALGOL 68|Revision 1 - one minor extension to language used - PRAGMA READ, similar to C's #include directive.}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.3.23 algol68g-2.3.23].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: Template.Big_float.Multiplication.a68'''<syntaxhighlight lang="algol68">##########################################
'''File: Mixin_Big_float_multiplication.a68'''
# TASK CODE #
<lang algol68># Kudos: use http://en.wikipedia.org/wiki/Karatsuba_algorithm #
# Actual generic mulitplication operator #
##########################################
# Alternatively use http://en.wikipedia.org/wiki/Karatsuba_algorithm #
 
OP * = (DIGITS a, b)DIGITS: (
DIGITS minus one = -IDENTITY LOC DIGITS,
zero = ZERO LOC DIGITS,
one = IDENTITY LOC DIGITS;
INT order = digit order OF arithmetic;
IF SIGN a = 0 OR SIGN b = 0 THEN zero
CO # Note: The following require the inequality operators #
ELIF a = one THEN b
ELIF b = one THEN a
ELIF a = minus one THEN -b
ELIF b = minus one THEN -a
END CO
ELSE
DIGIT zero = ZERO LOC DIGIT;
DIGIT one = IDENTITY LOC DIGIT;
[order + MSD a+MSD b: LSD a+LSD b]DIGIT a x b;
 
FOR place FROM LSD a+LSD b BY order TO LSD a+MSD b DO
a x b[place] := zero # pad the MSDs of the result with Zero #
OD;
FOR place a FROM LSD a BY order TO MSD a DO
DIGIT digit a = a[place a];
DIGIT carry := zero;
FOR place b FROM LSD b BY order TO MSD b DO
DIGIT digit b = b[place b];
REF DIGIT digit ab = a x b[place a + place b];
IF carry OF arithmetic THEN # used for big number arithmetic #
MOID(carry := ( digit ab +:= carry ));
DIGIT prod := digit a;
MOID(carry +:= ( prod *:= digit b ));
MOID(carry +:= ( digit ab +:= prod ))
ELSE # carry = 0 so we can just ignore the carry #
DIGIT prod := digit a;
MOID(prod *:= digit b);
MOID(digit ab +:= prod)
FI
OD;
a x b[place a + MSD b + order] := carry
OD;
INITDIGITS a x b # normalise #
FI
);
 
######################################
# Define the hybrid multiplication #
# operators for the generalised base #
######################################
 
OP * = (DIGIT a, DIGITS b)DIGITS: INITDIGITS a * b;
OP * = (DIGITS a, DIGIT b)DIGITS: a * INITDIGITS b;
 
OP *:= = (REF DIGITS in alhs, inDIGIT barg)DIGITS:( lhs := lhs * INITDIGITS arg;
</syntaxhighlight>'''File: Template.Balanced_ternary_float.Base.a68'''<syntaxhighlight lang="algol68">PR READ "Template.Big_float_BCD.Base.a68" PR # [[rc:Generalised floating point addition]] #
# Note: is cast really needed? eg. []STRUCTDIGIT(~) #
[]DIGIT a = digit OF []STRUCTDIGIT(digits OF in a);
[]DIGIT b = digit OF []STRUCTDIGIT(digits OF in b);
[digit order + MSD in a+MSD in b: LSD in a+LSD in b]DIGIT a times b;
 
################################################################
DIGIT zero := digit OF (INITSTRUCTDIGIT 0);
# First: define the attributes of the arithmetic we are using. #
################################################################
arithmetic := (
# balanced = # TRUE,
# carry = # TRUE,
# base = # 3, # width = # 1, # places = # 81, # order = # -1,
# repr = # USTRING("-","0","+")[@-1]
);
 
OP INITDIGIT = (CHAR c)DIGIT: (
FOR place FROM LSD in a+LSD in b BY digit order TO LSD in a+MSD in b DO
DIGIT out;
a times b[place] := zero
digit OF out :=
IF c = "+" THEN +1
ELIF c = "0" THEN 0
ELIF c = "-" THEN -1
ELSE raise value error("Unknown digit :"""+c+""""); SKIP
FI;
out
);
 
OP INITBIGREAL = (STRING s)BIGREAL: (
BIGREAL out;
BIGREAL base of arithmetic = INITBIGREAL base OF arithmetic; # Todo: Opt #
INT point := UPB s; # put the point on the extreme right #
FOR place FROM LWB s TO UPB s DO
IF s[place]="." THEN
point := place
ELSE
out := out SHR digit order OF arithmetic + INITDIGIT s[place]
FI
OD;
out SHR (UPB s-point)
FOR place a FROM LSD in a BY digit order TO MSD in a DO
);</syntaxhighlight>'''File: test.Balanced_ternary_float.Multiplication.a68'''<syntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
DIGIT digit a = a[place a];
####################################################################
DIGIT carry := zero;
# A program to test arbitrary length floating point multiplication #
FOR place b FROM LSD in b BY digit order TO MSD in b DO
####################################################################
DIGIT digit b = b[place b];
REF DIGIT digit ab = a times b[place a + place b];
 
PR READ "prelude/general.a68" PR # [[rc:Template:ALGOL 68/prelude]] #
IF digit carry THEN # used for big number arithmetic #
 
MOID(carry := ( digit ab +:= carry ));
PR READ "Template.Big_float.Multiplication.a68" PR
DIGIT prod := digit a;
 
MOID(carry +:= ( prod *:= digit b ));
# include the basic axioms of the digits being used #
MOID(carry +:= ( digit ab +:= prod ))
PR READ "Template.Balanced_ternary_float.Base.a68" PR
ELSE
 
DIGIT prod := digit a;
PR READ "Template.Big_float.Addition.a68" PR # [[rc:Generalised floating point addition]] #
MOID(prod *:= digit b);
PR READ "Template.Big_float.Subtraction.a68" PR # [[rc:Generalised floating point addition]] #
MOID(digit ab +:= prod)
 
FI
test1:( # Basic arithmetic #
OD;
INT rw = long real width;
a times b[place a + MSD in b + digit order] := carry
BIGREAL a = INITBIGREAL "+-0++0+.+-0++0+", # 523.239... #
b = INITBIGREAL - LONG 436.436,
c = INITBIGREAL "+-++-.+-++-"; # 65.267... #
printf(($g 9k g(rw,rw-5)39kgl$,
"a =",INITLONGREAL a, REPR a,
"b =",INITLONGREAL b, REPR b,
"c =",INITLONGREAL c, REPR c,
"a*(b-c)",INITLONGREAL(a*(b-c)), REPR(a*(b-c)),
$l$))
);
 
test2:( # A floating point Ternary multiplication table #
FORMAT s = $"|"$; # field seperator #
 
INT lwb = 1, tab = 8, upb = 12;
 
printf($"# "f(s)" * "f(s)$);
FOR j FROM lwb TO upb DO
FORMAT col = $n(tab)k f(s)$;
printf(($g" #"g(0)f(col)$, REPR INITBIGREAL j,j))
OD;
printf($l$);
FOR i FROM lwb TO 27 DO
printf(($g(0) 3k f(s) g 9k f(s)$,i,REPR INITBIGREAL i));
FOR j FROM lwb TO i MIN upb DO
FORMAT col = $n(tab)k f(s)$;
BIGREAL product = INITBIGREAL i * INITBIGREAL j;
printf(($gf(col)$, REPR product))
OD;
IF upb > i THEN printf($n(upb-i)(n(tab-1)x f(s))$) FI;
printf($l$)
OD
)</syntaxhighlight>'''Output:'''
<pre>
a = +523.23914037494284407864655 +-0++0+.+-0++0+
b = -436.43600000000000000000000 -++-0--.--0+-00+++-0-+---0-+0++++0--0000+00-+-+--+0-0-00--++0-+00---+0+-+++0+-0----0++
c = +65.26748971193415637860082 +-++-.+-++-
a*(b-c) -262510.90267998140903693919 ----000-0+0+.0+0-0-00---00--0-0+--+--00-0++-000++0-000-+0+-----+++-+-0+-+0+0++0+0-++-++0+---00++++
 
# | * |+ #1 |+- #2 |+0 #3 |++ #4 |+-- #5 |+-0 #6 |+-+ #7 |+0- #8 |+e+- #9|+0+ #10|++- #11|++0 #12|
INITDIGITS digits normalise(a times b)
1 |+ |+ | | | | | | | | | | | |
);</lang>'''File: test_Big_float_BCD_multiplication.a68'''
2 |+- |+- |++ | | | | | | | | | | |
<lang algol68>#!/usr/local/bin/a68g --script #
3 |+0 |+0 |+-0 |+e+- | | | | | | | | | |
4 |++ |++ |+0- |++0 |+--+ | | | | | | | | |
5 |+-- |+-- |+0+ |+--0 |+-+- |+0-+ | | | | | | | |
6 |+-0 |+-0 |++0 |+-e+- |+0-0 |+0+0 |++e+- | | | | | | |
7 |+-+ |+-+ |+--- |+-+0 |+00+ |++0- |+---0 |+--++ | | | | | |
8 |+0- |+0- |+--+ |+0-0 |++-- |++++ |+--+0 |+-0+- |+-+0+ | | | | |
9 |+e+- |+e+- |+-e+- |+e+0 |++e+- |+--e+- |+-e+0 |+-+e+- |+0-e+- |+e++ | | | |
10|+0+ |+0+ |+-+- |+0+0 |++++ |+-0-- |+-+-0 |+0--+ |+000- |+0+e+- |++-0+ | | |
11|++- |++- |+-++ |++-0 |+--0- |+-00+ |+-++0 |+00-- |+0+-+ |++-e+- |++0+- |+++++ | |
12|++0 |++0 |+0-0 |++e+- |+--+0 |+-+-0 |+0-e+- |+00+0 |++--0 |++e+0 |++++0 |+--0-0 |+--+e+-|
13|+++ |+++ |+00- |+++0 |+-0-+ |+-++- |+00-0 |+0+0+ |++0-- |+++e+- |+---++ |+--+0- |+-0-+0 |
14|+--- |+--- |+00+ |+---0 |+-0+- |+0--+ |+00+0 |++-0- |++0++ |+---e+-|+--+-- |+-0-0+ |+-0+-0 |
15|+--0 |+--0 |+0+0 |+--e+- |+-+-0 |+0-+0 |+0+e+- |++0-0 |++++0 |+--e+0 |+-0--0 |+-00+0 |+-+-e+-|
16|+--+ |+--+ |++-- |+--+0 |+-+0+ |+000- |++--0 |++0++ |+---+- |+--+e+-|+-00-+ |+-+--- |+-+0+0 |
17|+-0- |+-0- |++-+ |+-0-0 |+0--- |+00++ |++-+0 |++++- |+--00+ |+-0-e+-|+-0+0- |+-+0-+ |+0---0 |
18|+-e+-|+-e+- |++e+- |+-e+0 |+0-e+- |+0+e+- |++e+0 |+---e+-|+--+e+-|+-e++ |+-+-e+-|+-++e+-|+0-e+0 |
19|+-0+ |+-0+ |+++- |+-0+0 |+0-++ |++--- |+++-0 |+--0-+ |+-0-0- |+-0+e+-|+-+00+ |+0--+- |+0-++0 |
20|+-+- |+-+- |++++ |+-+-0 |+000- |++-0+ |++++0 |+--+-- |+-00-+ |+-+-e+-|+-+++- |+0-0++ |+000-0 |
21|+-+0 |+-+0 |+---0 |+-+e+- |+00+0 |++0-0 |+---e+-|+--++0 |+-0+-0 |+-+e+0 |+0--+0 |+00--0 |+00+e+-|
22|+-++ |+-++ |+--0- |+-++0 |+0+-+ |++0+- |+--0-0 |+-0-0+ |+-+--- |+-++e+-|+0-0++ |+0000- |+0+-+0 |
23|+0-- |+0-- |+--0+ |+0--0 |+0++- |+++-+ |+--0+0 |+-000- |+-+-++ |+0--e+-|+00--- |+00+0+ |+0++-0 |
24|+0-0 |+0-0 |+--+0 |+0-e+- |++--0 |++++0 |+--+e+-|+-0+-0 |+-+0+0 |+0-e+0 |+000-0 |+0+-+0 |++--e+-|
25|+0-+ |+0-+ |+-0-- |+0-+0 |++-0+ |+---0- |+-0--0 |+-0+++ |+-+++- |+0-+e+-|+00+-+ |+0++-- |++-0+0 |
26|+00- |+00- |+-0-+ |+00-0 |++0-- |+---++ |+-0-+0 |+-+-+- |+0--0+ |+00-e+-|+0+-0- |++---+ |++0--0 |
27|+e+0 |+e+0 |+-e+0 |+e++ |++e+0 |+--e+0 |+-e++ |+-+e+0 |+0-e+0 |+e+-- |+0+e+0 |++-e+0 |++e++ |
 
</pre>
##################################################################
# A program to test abritary length BCD floating point addition. #
##################################################################
 
=={{header|Go}}==
PR READ "prelude/general.a68" PR
{{trans|Phix}}
In the interests of brevity many of the comments and all of the commented-out code has been omitted.
<syntaxhighlight lang="go">package main
 
import (
INT digit width := 1; # define how decimal digits each "big" DIGIT is #
"fmt"
"log"
"math"
"strings"
)
 
const (
# include the basic axioms of the digits being used #
maxdp = 81
PR READ "Big_float_BCD_base.a68" PR
binary = "01"
PR READ "Mixin_Big_float_addition.a68" PR
ternary = "012"
PR READ "Mixin_Big_float_subtraction.a68" PR
balancedTernary = "-0+"
PR READ "Mixin_Big_float_multiplication.a68" PR
decimal = "0123456789"
hexadecimal = "0123456789ABCDEF"
septemVigesimal = "0123456789ABCDEFGHIJKLMNOPQ"
balancedBase27 = "ZYXWVUTSRQPON0ABCDEFGHIJKLM"
base37 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
 
/* helper functions */
test: (
BIGREAL pattern = INITBIGREAL 111111111,
INT pattern width = 9;
 
func changeByte(s string, idx int, c byte) string {
BIGREAL
sumbytes := INITBIGREAL 0,[]byte(s)
shiftedbytes[idx] pattern := pattern,c
return string(bytes)
tiny := INITBIGREAL 2, # typically 0.000.....00002 #
}
very tiny := INITBIGREAL -1;# typically 0.000.....00001 #
 
func removeByte(s string, idx int) string {
INT start = -8;
le := len(s)
bytes := []byte(s)
copy(bytes[idx:], bytes[idx+1:])
return string(bytes[0 : le-1])
}
 
func insertByte(s string, idx int, c byte) string {
FOR term FROM start TO 20 DO
le := len(s)
t := make([]byte, le+1)
copy(t, s)
copy(t[idx+1:], t[idx:])
t[idx] = c
return string(t)
}
 
func prependByte(s string, c byte) string {
# First make shifted pattern smaller by shifting right by the pattern width #
le := len(s)
digits OF shifted pattern := (digits OF shifted pattern)[@term*pattern width+1];
bytes := make([]byte, le+1)
digits OF tiny := (digits OF tiny)[@(term+start+1)*pattern width];
copy(bytes[1:], s)
digits OF very tiny := (digits OF very tiny)[@2*(term+1)*pattern width];
bytes[0] = c
return string(bytes)
}
 
func abs(i int) int {
MOID(sum +:= shifted pattern);
if i < 0 {
return -i
}
return i
}
 
// converts Phix indices to Go
# Manually multiply by 81 by repeated addition #
func gIndex(pIndex, le int) int {
BIGREAL prod := sum * sum * INITBIGREAL 81;
if pIndex < 0 {
return pIndex + le
}
return pIndex - 1
}
 
func getCarry(digit, base int) int {
BIGREAL total = prod + tiny + very tiny;
if digit > base {
return 1
} else if digit < 1 {
return -1
}
return 0
}
 
// convert string 'b' to a decimal floating point number
IF term < -4 THEN
func b2dec(b, alphabet string) float64 {
print(( REPR sum,"**2 x 81 gives: ", REPR prod,
res := 0.0
", Plus:",REPR tiny, " + ",REPR very tiny, ", Gives: "))
base := len(alphabet)
ELSE
zdx := strings.IndexByte(alphabet, '0') + 1
print((LSD prod - MSD prod + 1," digit test result: "))
signed := zdx == 1 && b[0] == '-'
FI;
if signed {
printf(($g$, REPR total, $" => "b("Passed","Failed")"!"$, LSD total = MSD total, $l$))
b = b[1:]
}
le := len(b)
ndp := strings.IndexByte(b, '.') + 1
if ndp != 0 {
b = removeByte(b, ndp-1) // remove decimal point
ndp = le - ndp
}
for i := 1; i <= len(b); i++ {
idx := strings.IndexByte(alphabet, b[i-1]) + 1
res = float64(base)*res + float64(idx) - float64(zdx)
}
if ndp != 0 {
res /= math.Pow(float64(base), float64(ndp))
}
if signed {
res = -res
}
return res
}
 
// string 'b' can be balanced or unbalanced
OD
func negate(b, alphabet string) string {
)</lang>
if alphabet[0] == '0' {
'''Output:'''
if b != "0" {
<pre style="height:15ex;overflow:scroll">
if b[0] == '-' {
111111111e63**2 x 81 gives: 999999998000000001e126, Plus:2e135 + -1e126, Gives: 1e144 => Passed!
b = b[1:]
111111111111111111e54**2 x 81 gives: 999999999999999998000000000000000001e108, Plus:2e126 + -1e108, Gives: 1e144 => Passed!
} else {
111111111111111111111111111e45**2 x 81 gives: 999999999999999999999999998000000000000000000000000001e90, Plus:2e117 + -1e90, Gives: 1e144 => Passed!
b = prependByte(b, '-')
111111111111111111111111111111111111e36**2 x 81 gives: 999999999999999999999999999999999998000000000000000000000000000000000001e72, Plus:2e108 + -1e72, Gives: 1e144 => Passed!
+90 digit test result: 1e144 => Passed!}
}
+108 digit test result: 1e144 => Passed!
} else {
+126 digit test result: 1e144 => Passed!
+144 digitfor testi result:= 1e1441; i <=> Passed!len(b); i++ {
+162 digit test result: 1e144 =>if b[i-1] Passed!= '.' {
idx := strings.IndexByte(alphabet, b[i-1]) + 1
+180 digit test result: 1e144 => Passed!
gi := gIndex(-idx, len(alphabet))
+198 digit test result: 1e144 => Passed!
b = changeByte(b, i-1, alphabet[gi])
+216 digit test result: 1e144 => Passed!
+234 digit test result: 1e144 => Passed!}
}
+252 digit test result: 1e144 => Passed!
}
+270 digit test result: 1e144 => Passed!
return b
+288 digit test result: 1e144 => Passed!
}
+306 digit test result: 1e144 => Passed!
 
+324 digit test result: 1e144 => Passed!
func bTrim(b string) string {
+342 digit test result: 1e144 => Passed!
// trim trailing ".000"
+360 digit test result: 1e144 => Passed!
idx := strings.IndexByte(b, '.') + 1
+378 digit test result: 1e144 => Passed!
if idx != 0 {
+396 digit test result: 1e144 => Passed!
b = strings.TrimRight(strings.TrimRight(b, "0"), ".")
+414 digit test result: 1e144 => Passed!
}
+432 digit test result: 1e144 => Passed!
// trim leading zeros but not "0.nnn"
+450 digit test result: 1e144 => Passed!
for len(b) > +4681 digit&& testb[0] result:== 1e144'0' =>&& b[1] Passed!= '.' {
+486 digitb test= resultb[1: 1e144 => Passed!]
}
+504 digit test result: 1e144 => Passed!
return b
+522 digit test result: 1e144 => Passed!
}
 
// for balanced number systems only
func bCarry(digit, base, idx int, n, alphabet string) (int, string) {
carry := getCarry(digit, base)
if carry != 0 {
for i := idx; i >= 1; i-- {
if n[i-1] != '.' {
k := strings.IndexByte(alphabet, n[i-1]) + 1
if k < base {
n = changeByte(n, i-1, alphabet[k])
break
}
n = changeByte(n, i-1, alphabet[0])
}
}
digit -= base * carry
}
return digit, n
}
 
// convert a string from alphabet to alphabet2
func b2b(n, alphabet, alphabet2 string) string {
res, m := "0", ""
if n != "0" {
base := len(alphabet)
base2 := len(alphabet2)
zdx := strings.IndexByte(alphabet, '0') + 1
zdx2 := strings.IndexByte(alphabet2, '0') + 1
var carry, q, r, digit int
idx := strings.IndexByte(alphabet, n[0]) + 1
negative := (zdx == 1 && n[0] == '-') || (zdx != 1 && idx < zdx)
if negative {
n = negate(n, alphabet)
}
ndp := strings.IndexByte(n, '.') + 1
if ndp != 0 {
n, m = n[0:ndp-1], n[ndp:]
}
res = ""
for len(n) > 0 {
q = 0
for i := 1; i <= len(n); i++ {
digit = strings.IndexByte(alphabet, n[i-1]) + 1 - zdx
q = q*base + digit
r = abs(q) % base2
digit = abs(q)/base2 + zdx
if q < 0 {
digit--
}
if zdx != 1 {
digit, n = bCarry(digit, base, i-1, n, alphabet)
}
n = changeByte(n, i-1, alphabet[digit-1])
q = r
}
r += zdx2
if zdx2 != 1 {
r += carry
carry = getCarry(r, base2)
r -= base2 * carry
}
res = prependByte(res, alphabet2[r-1])
n = strings.TrimLeft(n, "0")
}
if carry != 0 {
res = prependByte(res, alphabet2[carry+zdx2-1])
}
if len(m) > 0 {
res += "."
ndp = 0
if zdx != 1 {
lm := len(m)
alphaNew := base37[0:len(alphabet)]
m = b2b(m, alphabet, alphaNew)
m = strings.Repeat("0", lm-len(m)) + m
alphabet = alphaNew
zdx = 1
}
for len(m) > 0 && ndp < maxdp {
q = 0
for i := len(m); i >= 1; i-- {
digit = strings.IndexByte(alphabet, m[i-1]) + 1 - zdx
q += digit * base2
r = abs(q)%base + zdx
q /= base
if q < 0 {
q--
}
m = changeByte(m, i-1, alphabet[r-1])
}
digit = q + zdx2
if zdx2 != 1 {
digit, res = bCarry(digit, base2, len(res), res, alphabet2)
}
res += string(alphabet2[digit-1])
m = strings.TrimRight(m, "0")
ndp++
}
}
res = bTrim(res)
if negative {
res = negate(res, alphabet2)
}
}
return res
}
 
// convert 'd' to a string in the specified base
func float2b(d float64, alphabet string) string {
base := len(alphabet)
zdx := strings.Index(alphabet, "0") + 1
carry := 0
neg := d < 0
if neg {
d = -d
}
res := ""
whole := int(d)
d -= float64(whole)
for {
ch := whole%base + zdx
if zdx != 1 {
ch += carry
carry = getCarry(ch, base)
ch -= base * carry
}
res = prependByte(res, alphabet[ch-1])
whole /= base
if whole == 0 {
break
}
}
if carry != 0 {
res = prependByte(res, alphabet[carry+zdx-1])
carry = 0
}
if d != 0 {
res += "."
ndp := 0
for d != 0 && ndp < maxdp {
d *= float64(base)
digit := int(d) + zdx
d -= float64(digit)
if zdx != 1 {
digit, res = bCarry(digit, base, len(res), res, alphabet)
}
res += string(alphabet[digit-1])
ndp++
}
}
if neg {
res = negate(res, alphabet)
}
return res
}
 
func bAdd(a, b, alphabet string) string {
base := len(alphabet)
zdx := strings.IndexByte(alphabet, '0') + 1
var carry, da, db, digit int
if zdx == 1 {
if a[0] == '-' {
return bSub(b, negate(a, alphabet), alphabet)
}
if b[0] == '-' {
return bSub(a, negate(b, alphabet), alphabet)
}
}
adt := strings.IndexByte(a, '.') + 1
bdt := strings.IndexByte(b, '.') + 1
if adt != 0 || bdt != 0 {
if adt != 0 {
adt = len(a) - adt + 1
gi := gIndex(-adt, len(a))
a = removeByte(a, gi)
}
if bdt != 0 {
bdt = len(b) - bdt + 1
gi := gIndex(-bdt, len(b))
b = removeByte(b, gi)
}
if bdt > adt {
a += strings.Repeat("0", bdt-adt)
adt = bdt
} else if adt > bdt {
b += strings.Repeat("0", adt-bdt)
}
}
if len(a) < len(b) {
a, b = b, a
}
for i := -1; i >= -len(a); i-- {
if i < -len(a) {
da = 0
} else {
da = strings.IndexByte(alphabet, a[len(a)+i]) + 1 - zdx
}
if i < -len(b) {
db = 0
} else {
db = strings.IndexByte(alphabet, b[len(b)+i]) + 1 - zdx
}
digit = da + db + carry + zdx
carry = getCarry(digit, base)
a = changeByte(a, i+len(a), alphabet[digit-carry*base-1])
if i < -len(b) && carry == 0 {
break
}
}
if carry != 0 {
a = prependByte(a, alphabet[carry+zdx-1])
}
if adt != 0 {
gi := gIndex(-adt+1, len(a))
a = insertByte(a, gi, '.')
}
a = bTrim(a)
return a
}
 
func aSmaller(a, b, alphabet string) bool {
if len(a) != len(b) {
log.Fatal("strings should be equal in length")
}
for i := 1; i <= len(a); i++ {
da := strings.IndexByte(alphabet, a[i-1]) + 1
db := strings.IndexByte(alphabet, b[i-1]) + 1
if da != db {
return da < db
}
}
return false
}
 
func bSub(a, b, alphabet string) string {
base := len(alphabet)
zdx := strings.IndexByte(alphabet, '0') + 1
var carry, da, db, digit int
if zdx == 1 {
if a[0] == '-' {
return negate(bAdd(negate(a, alphabet), b, alphabet), alphabet)
}
if b[0] == '-' {
return bAdd(a, negate(b, alphabet), alphabet)
}
}
adt := strings.Index(a, ".") + 1
bdt := strings.Index(b, ".") + 1
if adt != 0 || bdt != 0 {
if adt != 0 {
adt = len(a) - adt + 1
gi := gIndex(-adt, len(a))
a = removeByte(a, gi)
}
if bdt != 0 {
bdt = len(b) - bdt + 1
gi := gIndex(-bdt, len(b))
b = removeByte(b, gi)
}
if bdt > adt {
a += strings.Repeat("0", bdt-adt)
adt = bdt
} else if adt > bdt {
b += strings.Repeat("0", adt-bdt)
}
}
bNegate := false
if len(a) < len(b) || (len(a) == len(b) && aSmaller(a, b, alphabet)) {
bNegate = true
a, b = b, a
}
for i := -1; i >= -len(a); i-- {
if i < -len(a) {
da = 0
} else {
da = strings.IndexByte(alphabet, a[len(a)+i]) + 1 - zdx
}
if i < -len(b) {
db = 0
} else {
db = strings.IndexByte(alphabet, b[len(b)+i]) + 1 - zdx
}
digit = da - db - carry + zdx
carry = 0
if digit <= 0 {
carry = 1
}
a = changeByte(a, i+len(a), alphabet[digit+carry*base-1])
if i < -len(b) && carry == 0 {
break
}
}
if carry != 0 {
log.Fatal("carry should be zero")
}
if adt != 0 {
gi := gIndex(-adt+1, len(a))
a = insertByte(a, gi, '.')
}
a = bTrim(a)
if bNegate {
a = negate(a, alphabet)
}
return a
}
 
func bMul(a, b, alphabet string) string {
zdx := strings.IndexByte(alphabet, '0') + 1
dpa := strings.IndexByte(a, '.') + 1
dpb := strings.IndexByte(b, '.') + 1
ndp := 0
if dpa != 0 {
ndp += len(a) - dpa
a = removeByte(a, dpa-1)
}
if dpb != 0 {
ndp += len(b) - dpb
b = removeByte(b, dpb-1)
}
pos, res := a, "0"
if zdx != 1 {
// balanced number systems
neg := negate(pos, alphabet)
for i := len(b); i >= 1; i-- {
m := strings.IndexByte(alphabet, b[i-1]) + 1 - zdx
for m != 0 {
temp, temp2 := pos, -1
if m < 0 {
temp = neg
temp2 = 1
}
res = bAdd(res, temp, alphabet)
m += temp2
}
pos += "0"
neg += "0"
}
} else {
// non-balanced number systems
negative := false
if a[0] == '-' {
a = a[1:]
negative = true
}
if b[0] == '-' {
b = b[1:]
negative = !negative
}
for i := len(b); i >= 1; i-- {
m := strings.IndexByte(alphabet, b[i-1]) + 1 - zdx
for m > 0 {
res = bAdd(res, pos, alphabet)
m--
}
pos += "0"
}
if negative {
res = negate(res, alphabet)
}
}
if ndp != 0 {
gi := gIndex(-ndp, len(res))
res = insertByte(res, gi, '.')
}
res = bTrim(res)
return res
}
 
func multTable() {
fmt.Println("multiplication table")
fmt.Println("====================")
fmt.Printf("* |")
for j := 1; j <= 12; j++ {
fj := float64(j)
fmt.Printf(" #%s %3s |", float2b(fj, hexadecimal), float2b(fj, balancedTernary))
}
for i := 1; i <= 27; i++ {
fi := float64(i)
a := float2b(fi, balancedTernary)
fmt.Printf("\n%-2s|", float2b(fi, septemVigesimal))
for j := 1; j <= 12; j++ {
if j > i {
fmt.Printf(" |")
} else {
fj := float64(j)
b := float2b(fj, balancedTernary)
m := bMul(a, b, balancedTernary)
fmt.Printf(" %6s |", m)
}
}
}
fmt.Println()
}
 
func test(name, alphabet string) {
a := b2b("+-0++0+.+-0++0+", balancedTernary, alphabet)
b := b2b("-436.436", decimal, alphabet)
c := b2b("+-++-.+-++-", balancedTernary, alphabet)
d := bSub(b, c, alphabet)
r := bMul(a, d, alphabet)
fmt.Printf("%s\n%s\n", name, strings.Repeat("=", len(name)))
fmt.Printf(" a = %.16g %s\n", b2dec(a, alphabet), a)
fmt.Printf(" b = %.16g %s\n", b2dec(b, alphabet), b)
fmt.Printf(" c = %.16g %s\n", b2dec(c, alphabet), c)
fmt.Printf("a*(b-c) = %.16g %s\n\n", b2dec(r, alphabet), r)
}
 
func main() {
test("balanced ternary", balancedTernary)
test("balanced base 27", balancedBase27)
test("decimal", decimal)
test("binary", binary)
test("ternary", ternary)
test("hexadecimal", hexadecimal)
test("septemvigesimal", septemVigesimal)
multTable()
}</syntaxhighlight>
 
{{out}}
<pre>
balanced ternary
================
a = 523.2391403749428 +-0++0+.+-0++0+
b = -436.4359999999999 -++-0--.--0+-00+++-0-+---0-+0++++0--0000+00-+-+--+0-0-00--++0-+00---+0+-+++0+-0----0++
c = 65.26748971193416 +-++-.+-++-
a*(b-c) = -262510.9026799813 ----000-0+0+.0+0-0-00---00--0-0+--+--00-0++-000++0-000-+0+-----+++-+-0+-+0+0++0+0-++-++0+---00++++
 
balanced base 27
================
a = 523.2391403749428 AUJ.FLI
b = -436.4359999999999 NKQ.YFDFTYSMHVANGXPVXHIZJRJWZD0PBGFJAEBAKOZODLY0ITEHPQLSQSGLFZUINATKCIKUVMWEWJMQ0COTS
c = 65.26748971193416 BK.GF
a*(b-c) = -262510.9026799812 ZVPJ.CWNYQPEENDVDPNJZXKFGCLHKLCX0YIBOMETHFWWBTVUFAH0SEZMTBJDCRRAQIQCAWMKXSTPYUXYPK0LODUO
 
decimal
=======
a = 523.2391403749428 523.239140374942844078646547782350251486053955189757658893461362597165066300868770004
b = -436.436 -436.436
c = 65.26748971193413 65.267489711934156378600823045267489711934156378600823045267489711934156378600823045
a*(b-c) = -262510.9026799813 -262510.90267998140903693918986303277315826215892262734715612833785876513103053772667101895163734826631742752252837097627017862754285047634638652268078676654605120794218
 
binary
======
a = 523.2391403749427 1000001011.001111010011100001001101101110011000100001011110100101001010100100000111001000111
b = -436.436 -110110100.011011111001110110110010001011010000111001010110000001000001100010010011011101001
c = 65.26748971193416 1000001.01000100011110100011010010101100110001100000111010111111101111001001001101111101
a*(b-c) = -262510.9026799814 -1000000000101101110.111001110001011000001001000001101110011111011100000100000100001000101011100011110010110001010100110111001011101001010000001110110100111110001101000000001111110101
 
ternary
=======
a = 523.2391403749428 201101.0201101
b = -436.4360000000002 -121011.102202211210021110012111201022222000202102010100101200200110122011122101110212
c = 65.26748971193416 2102.02102
a*(b-c) = -262510.9026799813 -111100002121.2201010011100110022102110002120222120100001221111011202022012121122001201122110221112
 
hexadecimal
===========
a = 523.2391403749427 20B.3D384DB9885E94A90723EF9CBCB174B443E45FFC41152FE0293416F15E3AC303A0F3799ED81589C62
b = -436.436 -1B4.6F9DB22D0E5604189374BC6A7EF9DB22D0E5604189374BC6A7EF9DB22D0E5604189374BC6A7EF9DB2
c = 65.26748971193416 41.447A34ACC60EBFBC937D5DC2E5A99CF8A021B641511E8D2B3183AFEF24DF5770B96A673E28086D905
a*(b-c) = -262510.9026799814 -4016E.E7160906E7DC10422DA508321819F4A637E5AEE668ED5163B12FCB17A732442F589975B7F24112B2E8F6E95EAD45803915EE26D20DF323D67CAEEC75D7BED68AA34E02F2B492257D66F028545FB398F60E
 
septemvigesimal
===============
a = 523.2391403749428 JA.6C9
b = -436.4359999999999 -G4.BKML7C5DJ8Q0KB39AIICH4HACN02OJKGPLOPG2D1MFBQI6LJ33F645JELD7I0Q6FNHG88E9M9GE3QO276
c = 65.26748971193416 2B.76
a*(b-c) = -262510.9026799812 -D92G.OA1C42LM0N8N30HDAFKJNEIFEOB0BHP1DM6ILA9P797KPJ05MCE6OGMO54Q3I3NQ9DGB673C8BC2FQF1N82
 
multiplication table
====================
* | #1 + | #2 +- | #3 +0 | #4 ++ | #5 +-- | #6 +-0 | #7 +-+ | #8 +0- | #9 +00 | #A +0+ | #B ++- | #C ++0 |
1 | + | | | | | | | | | | | |
2 | +- | ++ | | | | | | | | | | |
3 | +0 | +-0 | +00 | | | | | | | | | |
4 | ++ | +0- | ++0 | +--+ | | | | | | | | |
5 | +-- | +0+ | +--0 | +-+- | +0-+ | | | | | | | |
6 | +-0 | ++0 | +-00 | +0-0 | +0+0 | ++00 | | | | | | |
7 | +-+ | +--- | +-+0 | +00+ | ++0- | +---0 | +--++ | | | | | |
8 | +0- | +--+ | +0-0 | ++-- | ++++ | +--+0 | +-0+- | +-+0+ | | | | |
9 | +00 | +-00 | +000 | ++00 | +--00 | +-000 | +-+00 | +0-00 | +0000 | | | |
A | +0+ | +-+- | +0+0 | ++++ | +-0-- | +-+-0 | +0--+ | +000- | +0+00 | ++-0+ | | |
B | ++- | +-++ | ++-0 | +--0- | +-00+ | +-++0 | +00-- | +0+-+ | ++-00 | ++0+- | +++++ | |
C | ++0 | +0-0 | ++00 | +--+0 | +-+-0 | +0-00 | +00+0 | ++--0 | ++000 | ++++0 | +--0-0 | +--+00 |
D | +++ | +00- | +++0 | +-0-+ | +-++- | +00-0 | +0+0+ | ++0-- | +++00 | +---++ | +--+0- | +-0-+0 |
E | +--- | +00+ | +---0 | +-0+- | +0--+ | +00+0 | ++-0- | ++0++ | +---00 | +--+-- | +-0-0+ | +-0+-0 |
F | +--0 | +0+0 | +--00 | +-+-0 | +0-+0 | +0+00 | ++0-0 | ++++0 | +--000 | +-0--0 | +-00+0 | +-+-00 |
G | +--+ | ++-- | +--+0 | +-+0+ | +000- | ++--0 | ++0++ | +---+- | +--+00 | +-00-+ | +-+--- | +-+0+0 |
H | +-0- | ++-+ | +-0-0 | +0--- | +00++ | ++-+0 | ++++- | +--00+ | +-0-00 | +-0+0- | +-+0-+ | +0---0 |
I | +-00 | ++00 | +-000 | +0-00 | +0+00 | ++000 | +---00 | +--+00 | +-0000 | +-+-00 | +-++00 | +0-000 |
J | +-0+ | +++- | +-0+0 | +0-++ | ++--- | +++-0 | +--0-+ | +-0-0- | +-0+00 | +-+00+ | +0--+- | +0-++0 |
K | +-+- | ++++ | +-+-0 | +000- | ++-0+ | ++++0 | +--+-- | +-00-+ | +-+-00 | +-+++- | +0-0++ | +000-0 |
L | +-+0 | +---0 | +-+00 | +00+0 | ++0-0 | +---00 | +--++0 | +-0+-0 | +-+000 | +0--+0 | +00--0 | +00+00 |
M | +-++ | +--0- | +-++0 | +0+-+ | ++0+- | +--0-0 | +-0-0+ | +-+--- | +-++00 | +0-0++ | +0000- | +0+-+0 |
N | +0-- | +--0+ | +0--0 | +0++- | +++-+ | +--0+0 | +-000- | +-+-++ | +0--00 | +00--- | +00+0+ | +0++-0 |
O | +0-0 | +--+0 | +0-00 | ++--0 | ++++0 | +--+00 | +-0+-0 | +-+0+0 | +0-000 | +000-0 | +0+-+0 | ++--00 |
P | +0-+ | +-0-- | +0-+0 | ++-0+ | +---0- | +-0--0 | +-0+++ | +-+++- | +0-+00 | +00+-+ | +0++-- | ++-0+0 |
Q | +00- | +-0-+ | +00-0 | ++0-- | +---++ | +-0-+0 | +-+-+- | +0--0+ | +00-00 | +0+-0- | ++---+ | ++0--0 |
10| +000 | +-000 | +0000 | ++000 | +--000 | +-0000 | +-+000 | +0-000 | +00000 | +0+000 | ++-000 | ++0000 |
</pre>
 
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Formatting
import Base.BigInt, Base.BigFloat, Base.print, Base.+, Base.-, Base.*
 
abstract type BalancedBaseDigitArray end
 
mutable struct BalancedTernary <: BalancedBaseDigitArray
dig::Vector{Int8}
p::Int
BalancedTernary(arr::Vector, i) = new(Int8.(arr), i)
end
 
const MAX_PRECISION = 81
 
function BalancedTernary(s::String)
if (i = findfirst(x -> x == '.', s)) != nothing
p = length(s) - i
s = s[1:i-1] * s[i+1:end]
else
p = 0
end
b = BalancedTernary([c == '-' ? -1 : c == '0' ? 0 : 1 for c in s], p) # 2
end
 
function BalancedTernary(n::Integer) # 1, 3
if n < 0
return -BalancedTernary(-n)
elseif n == 0
return BalancedTernary([0], 0)
else
return canonicalize!(BalancedTernary(reverse(digits(n, base=3)), 0))
end
end
BalancedTernary() = BalancedTernary(0)
 
function BalancedTernary(x::Real) # 1, 3
if x < 0
return -BalancedTernary(-x)
end
arr = reverse(digits(BigInt(round(x * big"3.0"^MAX_PRECISION)), base=3))
return canonicalize!(BalancedTernary(arr, MAX_PRECISION))
end
 
function String(b::BalancedTernary) # 3
canonicalize!(b)
s = String([['-', '0', '+'][c + 2] for c in b.dig])
if b.p > 0
if b.p < length(s)
s = s[1:end-b.p] * "." * s[end-b.p+1:end]
elseif b.p == length(s)
s = "0." * s
else
s = "0." * "0"^(b.p - length(s)) * s
end
end
return s
end
 
function BigInt(b::BalancedTernary)
canonicalize!(b)
if b.p > 0
throw(InexactError("$(b.p) places after decimal point"))
end
return sum(t -> BigInt(3)^(t[1] - 1) * t[2], enumerate(reverse(b.dig))) # 3
end
 
BigFloat(b::BalancedTernary) = BigInt(BalancedTernary(b.dig, 0)) / big"3.0"^(b.p)
 
function canonicalize!(b::BalancedTernary)
for i in length(b.dig):-1:1
if b.dig[i] > 1
b.dig[i] -= 3
if i == 1
pushfirst!(b.dig, 1)
else
b.dig[i - 1] += 1
end
elseif b.dig[i] < -1
b.dig[i] += 3
if i == 1
pushfirst!(b.dig, -1)
else
b.dig[i - 1] -= 1
end
end
end
if (i = findfirst(x -> x != 0, b.dig)) != nothing
if i > 1
b.dig = b.dig[i:end]
end
else
b.dig = [0]
end
if b.p > 0 && (i = findlast(x -> x != 0, b.dig)) != nothing
removable = min(b.p, length(b.dig) - i)
b.dig = b.dig[1:end-removable]
b.p -= removable
end
return b
end
 
# The following should work with any base number where dig, p are a similar array and Int
# and the proper constructors, canon, and conversion routines are defined # 6
 
Base.print(io::IO, b::BalancedBaseDigitArray) = print(io, String(b))
 
function +(b1::T, b2::T) where T <: BalancedBaseDigitArray # 4
if all(x -> x == 0, b1.dig)
return deepcopy(b2)
elseif all(x -> x == 0, b2.dig)
return deepcopy(b1)
end
ldigits1 = length(b1.dig) - b1.p
arr = b1.dig[1:ldigits1]
ldigits2 = length(b2.dig) - b2.p
arr2 = b2.dig[1:ldigits2]
if (i = ldigits1 - ldigits2) > 0
arr2 = [zeros(Int8, i); arr2]
elseif i < 0
arr = [zeros(Int8, -i); arr]
end
if (i = b1.p - b2.p) > 0
arr = [arr; b1.dig[ldigits1+1:end]]
arr2 = [arr2; b2.dig[ldigits2+1:end]; zeros(Int8, i)]
elseif i < 0
arr = [arr; b1.dig[ldigits1+1:end]; zeros(Int8, -i)]
arr2 = [arr2; b2.dig[ldigits2+1:end]]
else
arr = [arr; b1.dig[ldigits1+1:end]]
arr2 = [arr2; b2.dig[ldigits2+1:end]]
end
arr .+= arr2
return canonicalize!(T(arr, max(b1.p, b2.p)))
end
 
-(b1::T) where T <: BalancedBaseDigitArray = T(b1.dig .* -1, b1.p) # 4
-(b1::T, b2::T) where T <: BalancedBaseDigitArray = +(b1, -b2) # 4
 
function *(b1::T, b2::T) where T <: BalancedBaseDigitArray # 4
len = length(b2.dig)
bsum = T()
for i in len:-1:1
bsum += T([b1.dig .* b2.dig[i]; zeros(Int8, len - i)], 0)
end
bsum.p = b1.p + b2.p
return canonicalize!(bsum)
end
 
function code_reuse_task(T::Type)
a = T("+-0++0+.+-0++0+")
b = T(-436.436)
c = T("+-++-.+-++-")
println(" a = ", a, " = ", format(BigFloat(a)))
println(" b = ", b, " = ", format(BigFloat(b)))
println(" c = ", c, " = ", format(BigFloat(c)))
println("\na * (b - c) = ", String(a * (b - c)), "\n = ", format(BigFloat(a * (b - c))))
 
println("\n Multiplication 27 X 12")
println(" x|+ (1) |+- (2) |+0 (3) |++ (4) |+-- (5)|+-0 (6)|+-+ (7)|+0- (8)|+e+-(9)|+0+(10)|++-(11)|++0(12)|")
for i in 1:27
print(lpad(i, 2), "|")
for j in 1:12
print(lpad(String(T(i * j)), 7), "|")
end
print("\n")
end
end
 
code_reuse_task(BalancedTernary)
</syntaxhighlight>{{out}}
<pre>
a = +-0++0+.+-0++0+ = 523.23914
b = -++-0--.--0+-00+++-0-+---0-+0++++0--++++0-+0+-0+0+-000-0----+0--0---+-000++--++-+-0--0-+ = -436.436
c = +-++-.+-++- = 65.26749
 
a * (b - c) = ----000-0+0+.0+0-0-00---00--0-0+--+0-0+0++-+-0--0--+0-++-0-+00-++0-0-0+++--0-+0--+-++-+-+-++-+0+-+-+
= -262510.90268
 
Multiplication 27 X 12
x|+ (1) |+- (2) |+0 (3) |++ (4) |+-- (5)|+-0 (6)|+-+ (7)|+0- (8)|+e+-(9)|+0+(10)|++-(11)|++0(12)|
1| +| +-| +0| ++| +--| +-0| +-+| +0-| +00| +0+| ++-| ++0|
2| +-| ++| +-0| +0-| +0+| ++0| +---| +--+| +-00| +-+-| +-++| +0-0|
3| +0| +-0| +00| ++0| +--0| +-00| +-+0| +0-0| +000| +0+0| ++-0| ++00|
4| ++| +0-| ++0| +--+| +-+-| +0-0| +00+| ++--| ++00| ++++| +--0-| +--+0|
5| +--| +0+| +--0| +-+-| +0-+| +0+0| ++0-| ++++| +--00| +-0--| +-00+| +-+-0|
6| +-0| ++0| +-00| +0-0| +0+0| ++00| +---0| +--+0| +-000| +-+-0| +-++0| +0-00|
7| +-+| +---| +-+0| +00+| ++0-| +---0| +--++| +-0+-| +-+00| +0--+| +00--| +00+0|
8| +0-| +--+| +0-0| ++--| ++++| +--+0| +-0+-| +-+0+| +0-00| +000-| +0+-+| ++--0|
9| +00| +-00| +000| ++00| +--00| +-000| +-+00| +0-00| +0000| +0+00| ++-00| ++000|
10| +0+| +-+-| +0+0| ++++| +-0--| +-+-0| +0--+| +000-| +0+00| ++-0+| ++0+-| ++++0|
11| ++-| +-++| ++-0| +--0-| +-00+| +-++0| +00--| +0+-+| ++-00| ++0+-| +++++| +--0-0|
12| ++0| +0-0| ++00| +--+0| +-+-0| +0-00| +00+0| ++--0| ++000| ++++0| +--0-0| +--+00|
13| +++| +00-| +++0| +-0-+| +-++-| +00-0| +0+0+| ++0--| +++00| +---++| +--+0-| +-0-+0|
14| +---| +00+| +---0| +-0+-| +0--+| +00+0| ++-0-| ++0++| +---00| +--+--| +-0-0+| +-0+-0|
15| +--0| +0+0| +--00| +-+-0| +0-+0| +0+00| ++0-0| ++++0| +--000| +-0--0| +-00+0| +-+-00|
16| +--+| ++--| +--+0| +-+0+| +000-| ++--0| ++0++| +---+-| +--+00| +-00-+| +-+---| +-+0+0|
17| +-0-| ++-+| +-0-0| +0---| +00++| ++-+0| ++++-| +--00+| +-0-00| +-0+0-| +-+0-+| +0---0|
18| +-00| ++00| +-000| +0-00| +0+00| ++000| +---00| +--+00| +-0000| +-+-00| +-++00| +0-000|
19| +-0+| +++-| +-0+0| +0-++| ++---| +++-0| +--0-+| +-0-0-| +-0+00| +-+00+| +0--+-| +0-++0|
20| +-+-| ++++| +-+-0| +000-| ++-0+| ++++0| +--+--| +-00-+| +-+-00| +-+++-| +0-0++| +000-0|
21| +-+0| +---0| +-+00| +00+0| ++0-0| +---00| +--++0| +-0+-0| +-+000| +0--+0| +00--0| +00+00|
22| +-++| +--0-| +-++0| +0+-+| ++0+-| +--0-0| +-0-0+| +-+---| +-++00| +0-0++| +0000-| +0+-+0|
23| +0--| +--0+| +0--0| +0++-| +++-+| +--0+0| +-000-| +-+-++| +0--00| +00---| +00+0+| +0++-0|
24| +0-0| +--+0| +0-00| ++--0| ++++0| +--+00| +-0+-0| +-+0+0| +0-000| +000-0| +0+-+0| ++--00|
25| +0-+| +-0--| +0-+0| ++-0+| +---0-| +-0--0| +-0+++| +-+++-| +0-+00| +00+-+| +0++--| ++-0+0|
26| +00-| +-0-+| +00-0| ++0--| +---++| +-0-+0| +-+-+-| +0--0+| +00-00| +0+-0-| ++---+| ++0--0|
27| +000| +-000| +0000| ++000| +--000| +-0000| +-+000| +0-000| +00000| +0+000| ++-000| ++0000|
</pre>
 
=={{header|Phix}}==
Note regarding requirement #5: While this meets my definition of "reasonably efficient",
it should not shock anyone that this kind of "string maths" which works digit-by-digit
and uses repeated addition (eg *999 performs 27 additions) could easily be 10,000 times
slower than raw hardware or a carefully optimised library such as gmp. However this does
offer perfect accuracy in any given base, whereas gmp, for all it's brilliance, can hold
0.1 accurate to several million decimal places, but just never quite exact.
 
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Generic_multiplication.exw</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAX_DP</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">81</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">binary</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"01"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">ternary</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"012"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">balancedternary</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"-0+"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">decimal</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0123456789"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">hexadecimal</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0123456789ABCDEF"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">septemvigesimal</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0123456789ABCDEFGHIJKLMNOPQ"</span><span style="color: #0000FF;">,</span>
<span style="color: #000080;font-style:italic;">-- heptavintimal = "0123456789ABCDEFGHKMNPRTVXZ", -- ??
-- wonky_donkey_26 = "0ABCDEFGHIJKLMNOPQRSTUVWXY",
-- wonky_donkey_27 = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ",</span>
<span style="color: #000000;">balanced_base27</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"ZYXWVUTSRQPON0ABCDEFGHIJKLM"</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">base37</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</span>
<span style="color: #000080;font-style:italic;">--
--Note: I have seen some schemes where balanced-base-27 uses
--==== the same character set as septemvigesimal, with 'D'
-- representing 0, and wonky_donkey_27 with 'M'==0(!).
-- These routines do not support that directly, except
-- (perhaps) via a simple mapping on all inputs/outputs.
-- It may be possible to add a defaulted parameter such
-- as zero='0' - left as an exercise for the reader.
-- Admittedly that balanced_base27 is entirely my own
-- invention, just for this specific task.
--</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">b2dec</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--
-- convert string b back into a normal (decimal) atom,
-- eg b2dec("+0-",balancedternary) yields 8
--</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">base</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">zdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">signed</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">signed</span> <span style="color: #008080;">then</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">ndp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ndp</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ndp</span><span style="color: #0000FF;">..</span><span style="color: #000000;">ndp</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #000080;font-style:italic;">-- remove '.'</span>
<span style="color: #000000;">ndp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">-</span><span style="color: #000000;">ndp</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">*</span><span style="color: #000000;">res</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ndp</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">/=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">base</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ndp</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">signed</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">res</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--
-- negate b (can be balanced or unbalanced)
--</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- traditional: add/remove a leading '-'
-- eg "-123" &lt;==&gt; "123"</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">"0"</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"-"</span><span style="color: #0000FF;">&</span><span style="color: #000000;">b</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">else</span>
<span style="color: #000080;font-style:italic;">-- balanced: mirror [non-0] digits
-- eg "-0+" (ie -8) &lt;==&gt; "+0-" (ie +8)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[-</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">b</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">b_trim</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- (common code)
-- trim trailing ".000"</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">),</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000080;font-style:italic;">-- trim leading zeroes, but not "0.nnn" -&gt; ".nnn"
-- [hence we cannot use the standard trim_head()]</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)></span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">b</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">b_carry</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">idx</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- (common code, for balanced number systems only)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">></span><span style="color: #000000;">base</span><span style="color: #0000FF;">?+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digit</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">idx</span> <span style="color: #008080;">to</span> <span style="color: #000000;">0</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;"><</span><span style="color: #000000;">base</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">*</span><span style="color: #000000;">carry</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">b2b</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet2</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--
-- convert a string from alphabet to alphabet2,
-- eg b2b("8",decimal,balancedternary) yields "+0-",
-- & b2b("+0-",balancedternary,decimal) yields "8",
--</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">"0"</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">base</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">base2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet2</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">zdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">zdx2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet2</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">digit</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">negative</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">((</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">or</span>
<span style="color: #0000FF;">(</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">negative</span> <span style="color: #008080;">then</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ndp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ndp</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">ndp</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ndp</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000080;font-style:italic;">--
-- this is a digit-by-digit divide (/mod) loop
-- eg for hex-&gt;decimal we would want:
-- this loop/modrem("FFFF",10) --&gt; "1999" rem 5,
-- this loop/modrem("1999",10) --&gt; "28F" rem 3,
-- this loop/modrem("28F",10) --&gt; "41" rem 5,
-- this loop/modrem("41",10) --&gt; "6" rem 5,
-- this loop/modrem("6",10) --&gt; "0" rem 6,
-- ==&gt; res:="65535" (in 5 full iterations over n).
--</span>
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">*</span><span style="color: #000000;">base</span><span style="color: #0000FF;">+</span><span style="color: #000000;">digit</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base2</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">/</span><span style="color: #000000;">base2</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">zdx</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_carry</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">n</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">zdx2</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx2</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">carry</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">></span><span style="color: #000000;">base2</span><span style="color: #0000FF;">?+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">base2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">carry</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">res</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_head</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">+</span><span style="color: #000000;">zdx2</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'.'</span>
<span style="color: #000000;">ndp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- convert fraction to unbalanced, to simplify the (other-base) multiply.</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">lm</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">alphanew</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">base37</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)]</span>
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b2b</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphanew</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (nb: no fractional part!)</span>
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lm</span><span style="color: #0000FF;">-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">))&</span><span style="color: #000000;">m</span> <span style="color: #000080;font-style:italic;">-- zero-pad if required</span>
<span style="color: #000000;">alphabet</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphanew</span>
<span style="color: #000000;">zdx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ndp</span><span style="color: #0000FF;"><</span><span style="color: #000000;">MAX_DP</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000080;font-style:italic;">--
-- this is a digit-by-digit multiply loop
-- eg for [.]"1415" decimal-&gt;decimal we
-- would repeatedly multiply by 10, giving
-- 1 and "4150", then 4 and "1500", then
-- 1 and "5000", then 5 and "0000". We
-- strip zeroes between each output digit
-- & obviously normally alphabet in!=out.
--</span>
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">*</span><span style="color: #000000;">base2</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">zdx</span>
<span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">/</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">q</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">zdx2</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx2</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_carry</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base2</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">),</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">alphabet2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_tail</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">ndp</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">negative</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet2</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">atm2b</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--
-- convert d to a string in the specified base,
-- eg atm2b(65535,hexadecimal) =&gt; "FFFF"
--
-- As a standard feature of phix, you can actually specify
-- d in any number base between 2 and 36, eg 0(13)168 is
-- equivalent to 255 (see test\t37misc.exw for more), but
-- not (yet) in balanced number bases, or with fractions,
-- except (of course) for normal decimal fractions.
--
-- Note that eg b2b("-436.436",decimal,balancedternary) is
-- more acccurate that atm2b(-436.436,balancedternary) due
-- to standard IEEE 754 floating point limitations.
-- For integers, discrepancies only creep in for values
-- outside the range +/-9,007,199,254,740,992 (on 32-bit).
-- However, this is much simpler and faster than b2b().
--</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">base</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">zdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">neg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">d</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">neg</span> <span style="color: #008080;">then</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">d</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">whole</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">whole</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">whole</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">zdx</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">carry</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #000000;">base</span><span style="color: #0000FF;">?+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">*</span><span style="color: #000000;">carry</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">res</span>
<span style="color: #000000;">whole</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">whole</span><span style="color: #0000FF;">/</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">whole</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">+</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">res</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'.'</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ndp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ndp</span><span style="color: #0000FF;"><</span><span style="color: #000000;">MAX_DP</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">base</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">d</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">zdx</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">digit</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_carry</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">),</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">ndp</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">neg</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">-- negative numbers in addition and subtraction
-- (esp. non-balanced) are treated as follows:
-- for -ve a: (-a)+b == b-a; (-a)-b == -(a+b)
-- for -ve b: a+(-b) == a-b; a-(-b) == a+b
-- for a&gt;b: a-b == -(b-a) [avoid running off end]</span>
<span style="color: #008080;">forward</span> <span style="color: #008080;">function</span> <span style="color: #000000;">b_sub</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">b_add</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">base</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">zdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">da</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">db</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">digit</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (-a)+b == b-a</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">b_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- a+(-b) == a-b</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">b_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">adt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">bdt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">adt</span> <span style="color: #008080;">or</span> <span style="color: #000000;">bdt</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- remove the '.'s and zero-pad the shorter as needed
-- (thereafter treat them as two whole integers)
-- eg "1.23"+"4.5" -&gt; "123"+"450" (leaving adt==2)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">adt</span> <span style="color: #008080;">then</span> <span style="color: #000000;">adt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bdt</span> <span style="color: #008080;">then</span> <span style="color: #000000;">bdt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bdt</span><span style="color: #0000FF;">></span><span style="color: #000000;">adt</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">adt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bdt</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">adt</span><span style="color: #0000FF;">></span><span style="color: #000000;">bdt</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">-</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)<</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">}</span> <span style="color: #000080;font-style:italic;">-- ensure b is the shorter</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #0000FF;">-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">da</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">db</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">da</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">db</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">carry</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">zdx</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">></span><span style="color: #000000;">base</span><span style="color: #0000FF;">?+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digit</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">-</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">*</span><span style="color: #000000;">base</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">carry</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">+</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">]&</span><span style="color: #000000;">a</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">adt</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">a</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"."</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">a</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">a_smaller</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- return true if a is smaller than b
-- if not balanced then both are +ve</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)!=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- sanity check</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">da</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">db</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">da</span><span style="color: #0000FF;">,</span><span style="color: #000000;">db</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">c</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #000080;font-style:italic;">-- (=, which is not &lt;)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">b_sub</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">base</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">zdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">da</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">db</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">digit</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (-a)-b == -(a+b)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- a-(-b) == a+b</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">b_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">adt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">bdt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">adt</span> <span style="color: #008080;">or</span> <span style="color: #000000;">bdt</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- remove the '.'s and zero-pad the shorter as needed
-- (thereafter treat them as two whole integers)
-- eg "1.23"+"4.5" -&gt; "123"+"450" (leaving adt==2)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">adt</span> <span style="color: #008080;">then</span> <span style="color: #000000;">adt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bdt</span> <span style="color: #008080;">then</span> <span style="color: #000000;">bdt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bdt</span><span style="color: #0000FF;">></span><span style="color: #000000;">adt</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">adt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bdt</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">adt</span><span style="color: #0000FF;">></span><span style="color: #000000;">bdt</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">-</span><span style="color: #000000;">bdt</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">bNegate</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)<</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">a_smaller</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">))</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">bNegate</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">}</span> <span style="color: #000080;font-style:italic;">-- ensure b is the shorter/smaller</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #0000FF;">-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">da</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">db</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;"><-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">da</span> <span style="color: #0000FF;">-</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">db</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">carry</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">zdx</span>
<span style="color: #000000;">carry</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0</span>
<span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">[</span><span style="color: #000000;">digit</span><span style="color: #0000FF;">+</span><span style="color: #000000;">carry</span><span style="color: #0000FF;">*</span><span style="color: #000000;">base</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #000000;">carry</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">carry</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- should have set bNegate above...</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">adt</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">a</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">adt</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"."</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">bNegate</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">a</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">b_mul</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">base</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">zdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">dpa</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">a</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">dpb</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">ndp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">dpa</span> <span style="color: #008080;">then</span> <span style="color: #000000;">ndp</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">dpa</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dpa</span><span style="color: #0000FF;">..</span><span style="color: #000000;">dpa</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">dpb</span> <span style="color: #008080;">then</span> <span style="color: #000000;">ndp</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">dpb</span><span style="color: #0000FF;">;</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dpb</span><span style="color: #0000FF;">..</span><span style="color: #000000;">dpb</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0"</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">zdx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- balanced number systems</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">neg</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">m</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #000000;">neg</span><span style="color: #0000FF;">:</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">),</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">m</span> <span style="color: #0000FF;">+=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'0'</span>
<span style="color: #000000;">neg</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'0'</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">else</span>
<span style="color: #000080;font-style:italic;">-- non-balanced (normal) number systems</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">negative</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$];</span> <span style="color: #000000;">negative</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'-'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$];</span> <span style="color: #000000;">negative</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">not</span> <span style="color: #000000;">negative</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">zdx</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">m</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">&=</span> <span style="color: #008000;">'0'</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">negative</span> <span style="color: #008080;">then</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">negate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ndp</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span><span style="color: #0000FF;">[-</span><span style="color: #000000;">ndp</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">ndp</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"."</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000080;font-style:italic;">-- [note 1] not surprisingly, the decimal output is somewhat cleaner/shorter when
-- the decimal string inputs for a and c are used, whereas tests 1/2/5/7
-- (the 3-based ones) look much better with all ternary string inputs.</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">name</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--string a = b2b("523.2391403749428",decimal,alphabet), -- [see note 1]</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b2b</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"+-0++0+.+-0++0+"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balancedternary</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b2b</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"-436.436"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">decimal</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000080;font-style:italic;">-- b = b2b("-++-0--.--0+-00+++-",balancedternary,alphabet),
-- c = b2b("65.26748971193416",decimal,alphabet), -- [see note 1]</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b2b</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"+-++-.+-++-"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balancedternary</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">name</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'='</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">name</span><span style="color: #0000FF;">))})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" a = %.16g %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">b2dec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">a</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" b = %.16g %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">b2dec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">b</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" c = %.16g %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">b2dec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">c</span><span style="color: #0000FF;">})</span>
<span style="color: #000080;font-style:italic;">-- printf(1," d = %.16g %s\n",{b2dec(d,alphabet),d})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a*(b-c) = %.16g %s\n\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">b2dec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span><span style="color: #000000;">alphabet</span><span style="color: #0000FF;">),</span><span style="color: #000000;">r</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"balanced ternary"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">balancedternary</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"balanced base 27"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">balanced_base27</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"decimal"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">decimal</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"binary"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">binary</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"ternary"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ternary</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"hexadecimal"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hexadecimal</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"septemvigesimal"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">septemvigesimal</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
The printed decimal output is inherently limited to IEEE 754 precision, hence I deliberately limited output (%.16g)
because it is silly to try and go any higher, whereas the output from b_mul() is actually perfectly accurate,
see [note 1] regarding decimal/ternary input, just above.
{{out}}
<pre>
balanced ternary
================
a = 523.2391403749428 +-0++0+.+-0++0+
b = -436.4359999999999 -++-0--.--0+-00+++-0-+---0-+0++++0--0000+00-+-+--+0-0-00--++0-+00---+0+-+++0+-0----0++
c = 65.26748971193416 +-++-.+-++-
a*(b-c) = -262510.9026799813 ----000-0+0+.0+0-0-00---00--0-0+--+--00-0++-000++0-000-+0+-----+++-+-0+-+0+0++0+0-++-++0+---00++++
 
balanced base 27
================
a = 523.2391403749428 AUJ.FLI
b = -436.436 NKQ.YFDFTYSMHVANGXPVXHIZJRJWZD0PBGFJAEBAKOZODLY0ITEHPQLSQSGLFZUINATKCIKUVMWEWJMQ0COTS
c = 65.26748971193416 BK.GF
a*(b-c) = -262510.9026799813 ZVPJ.CWNYQPEENDVDPNJZXKFGCLHKLCX0YIBOMETHFWWBTVUFAH0SEZMTBJDCRRAQIQCAWMKXSTPYUXYPK0LODUO
 
decimal
=======
a = 523.239140374943 523.239140374942844078646547782350251486053955189757658893461362597165066300868770004
b = -436.436 -436.436
c = 65.26748971193415 65.267489711934156378600823045267489711934156378600823045267489711934156378600823045
a*(b-c) = -262510.9026799814 -262510.90267998140903693918986303277315826215892262734715612833785876513103053772667101895163734826631742752252837097627017862754285047634638652268078676654605120794218
 
binary
======
a = 523.2391403749427 1000001011.001111010011100001001101101110011000100001011110100101001010100100000111001000111
b = -436.436 -110110100.011011111001110110110010001011010000111001010110000001000001100010010011011101001
c = 65.26748971193416 1000001.01000100011110100011010010101100110001100000111010111111101111001001001101111101
a*(b-c) = -262510.9026799814 -1000000000101101110.111001110001011000001001000001101110011111011100000100000100001000101011100011110010110001010100110111001011101001010000001110110100111110001101000000001111110101
 
ternary
=======
a = 523.2391403749428 201101.0201101
b = -436.4360000000001 -121011.102202211210021110012111201022222000202102010100101200200110122011122101110212
c = 65.26748971193416 2102.02102
a*(b-c) = -262510.9026799813 -111100002121.2201010011100110022102110002120222120100001221111011202022012121122001201122110221112
 
hexadecimal
===========
a = 523.2391403749427 20B.3D384DB9885E94A90723EF9CBCB174B443E45FFC41152FE0293416F15E3AC303A0F3799ED81589C62
b = -436.436 -1B4.6F9DB22D0E5604189374BC6A7EF9DB22D0E5604189374BC6A7EF9DB22D0E5604189374BC6A7EF9DB2
c = 65.26748971193416 41.447A34ACC60EBFBC937D5DC2E5A99CF8A021B641511E8D2B3183AFEF24DF5770B96A673E28086D905
a*(b-c) = -262510.9026799814 -4016E.E7160906E7DC10422DA508321819F4A637E5AEE668ED5163B12FCB17A732442F589975B7F24112B2E8F6E95EAD45803915EE26D20DF323D67CAEEC75D7BED68AA34E02F2B492257D66F028545FB398F60E
 
septemvigesimal
===============
a = 523.2391403749428 JA.6C9
b = -436.436 -G4.BKML7C5DJ8Q0KB39AIICH4HACN02OJKGPLOPG2D1MFBQI6LJ33F645JELD7I0Q6FNHG88E9M9GE3QO276
c = 65.26748971193416 2B.76
a*(b-c) = -262510.9026799813 -D92G.OA1C42LM0N8N30HDAFKJNEIFEOB0BHP1DM6ILA9P797KPJ05MCE6OGMO54Q3I3NQ9DGB673C8BC2FQF1N82
</pre>
 
=== multiplication table ===
Without e notation, with hexadecimal across, septemvigesimal down, and balanced ternary contents!
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"* |"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" #%s %3s |"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">atm2b</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">hexadecimal</span><span style="color: #0000FF;">),</span><span style="color: #000000;">atm2b</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balancedternary</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">27</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">atm2b</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balancedternary</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n%-2s|"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">atm2b</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">septemvigesimal</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">12</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">></span><span style="color: #000000;">i</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" |"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">atm2b</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balancedternary</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balancedternary</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %6s |"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">m</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
* | #1 + | #2 +- | #3 +0 | #4 ++ | #5 +-- | #6 +-0 | #7 +-+ | #8 +0- | #9 +00 | #A +0+ | #B ++- | #C ++0 |
1 | + | | | | | | | | | | | |
2 | +- | ++ | | | | | | | | | | |
3 | +0 | +-0 | +00 | | | | | | | | | |
4 | ++ | +0- | ++0 | +--+ | | | | | | | | |
5 | +-- | +0+ | +--0 | +-+- | +0-+ | | | | | | | |
6 | +-0 | ++0 | +-00 | +0-0 | +0+0 | ++00 | | | | | | |
7 | +-+ | +--- | +-+0 | +00+ | ++0- | +---0 | +--++ | | | | | |
8 | +0- | +--+ | +0-0 | ++-- | ++++ | +--+0 | +-0+- | +-+0+ | | | | |
9 | +00 | +-00 | +000 | ++00 | +--00 | +-000 | +-+00 | +0-00 | +0000 | | | |
A | +0+ | +-+- | +0+0 | ++++ | +-0-- | +-+-0 | +0--+ | +000- | +0+00 | ++-0+ | | |
B | ++- | +-++ | ++-0 | +--0- | +-00+ | +-++0 | +00-- | +0+-+ | ++-00 | ++0+- | +++++ | |
C | ++0 | +0-0 | ++00 | +--+0 | +-+-0 | +0-00 | +00+0 | ++--0 | ++000 | ++++0 | +--0-0 | +--+00 |
D | +++ | +00- | +++0 | +-0-+ | +-++- | +00-0 | +0+0+ | ++0-- | +++00 | +---++ | +--+0- | +-0-+0 |
E | +--- | +00+ | +---0 | +-0+- | +0--+ | +00+0 | ++-0- | ++0++ | +---00 | +--+-- | +-0-0+ | +-0+-0 |
F | +--0 | +0+0 | +--00 | +-+-0 | +0-+0 | +0+00 | ++0-0 | ++++0 | +--000 | +-0--0 | +-00+0 | +-+-00 |
G | +--+ | ++-- | +--+0 | +-+0+ | +000- | ++--0 | ++0++ | +---+- | +--+00 | +-00-+ | +-+--- | +-+0+0 |
H | +-0- | ++-+ | +-0-0 | +0--- | +00++ | ++-+0 | ++++- | +--00+ | +-0-00 | +-0+0- | +-+0-+ | +0---0 |
I | +-00 | ++00 | +-000 | +0-00 | +0+00 | ++000 | +---00 | +--+00 | +-0000 | +-+-00 | +-++00 | +0-000 |
J | +-0+ | +++- | +-0+0 | +0-++ | ++--- | +++-0 | +--0-+ | +-0-0- | +-0+00 | +-+00+ | +0--+- | +0-++0 |
K | +-+- | ++++ | +-+-0 | +000- | ++-0+ | ++++0 | +--+-- | +-00-+ | +-+-00 | +-+++- | +0-0++ | +000-0 |
L | +-+0 | +---0 | +-+00 | +00+0 | ++0-0 | +---00 | +--++0 | +-0+-0 | +-+000 | +0--+0 | +00--0 | +00+00 |
M | +-++ | +--0- | +-++0 | +0+-+ | ++0+- | +--0-0 | +-0-0+ | +-+--- | +-++00 | +0-0++ | +0000- | +0+-+0 |
N | +0-- | +--0+ | +0--0 | +0++- | +++-+ | +--0+0 | +-000- | +-+-++ | +0--00 | +00--- | +00+0+ | +0++-0 |
O | +0-0 | +--+0 | +0-00 | ++--0 | ++++0 | +--+00 | +-0+-0 | +-+0+0 | +0-000 | +000-0 | +0+-+0 | ++--00 |
P | +0-+ | +-0-- | +0-+0 | ++-0+ | +---0- | +-0--0 | +-0+++ | +-+++- | +0-+00 | +00+-+ | +0++-- | ++-0+0 |
Q | +00- | +-0-+ | +00-0 | ++0-- | +---++ | +-0-+0 | +-+-+- | +0--0+ | +00-00 | +0+-0- | ++---+ | ++0--0 |
10| +000 | +-000 | +0000 | ++000 | +--000 | +-0000 | +-+000 | +0-000 | +00000 | +0+000 | ++-000 | ++0000 |
</pre>
 
=={{header|Wren}}==
{{trans|Phix}}
{{libheader|Wren-str}}
{{libheader|Wren-iterate}}
{{libheader|Wren-fmt}}
Translated via the Go entry.
<syntaxhighlight lang="wren">import "./str" for Str
import "./iterate" for Stepped
import "./fmt" for Fmt
 
var maxdp = 81
var binary = "01"
var ternary = "012"
var balancedTernary = "-0+"
var decimal = "0123456789"
var hexadecimal = "0123456789ABCDEF"
var septemVigesimal = "0123456789ABCDEFGHIJKLMNOPQ"
var balancedBase27 = "ZYXWVUTSRQPON0ABCDEFGHIJKLM"
var base37 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
// converts Phix indices to Wren
var wIndex = Fn.new { |pIndex, le|
if (pIndex < 0) return pIndex + le
return pIndex - 1
}
 
var getCarry = Fn.new { |digit, base|
if (digit > base) {
return 1
} else if (digit < 1) {
return -1
}
return 0
}
 
// convert string 'b' to a decimal floating point number
var b2dec = Fn.new { |b, alphabet|
var res = 0
var base = alphabet.count
var zdx = alphabet.indexOf("0") + 1
var signed = zdx == 1 && b[0] == "-"
if (signed) b = b[1..-1]
var le = b.count
var ndp = b.indexOf(".") + 1
if (ndp != 0) {
b = Str.delete(b, ndp - 1) // remove decimal point
ndp = le - ndp
}
for (i in Stepped.ascend(1..b.count)) {
var idx = alphabet.indexOf(b[i-1]) + 1
res = base * res + idx - zdx
}
if (ndp != 0) res = res / base.pow(ndp)
if (signed) res = -res
return res
}
 
// string 'b' can be balanced or unbalanced
var negate = Fn.new { |b, alphabet|
if (alphabet[0] == "0") {
if (b != "0") b = (b[0] == "-") ? b[1..-1] : Str.insert(b, 0, "-")
} else {
for (i in Stepped.ascend(1..b.count)) {
if (b[i-1] != ".") {
var idx = alphabet.indexOf(b[i-1]) + 1
var wi = wIndex.call(-idx, alphabet.count)
b = Str.change(b, i-1, alphabet[wi])
}
}
}
return b
}
 
var bTrim = Fn.new { |b|
// trim trailing ".000"
var idx = b.indexOf(".") + 1
if (idx != 0) b = b.trimEnd("0").trimEnd(".")
// trim leading zeros but not "0.nnn"
while (b.count > 1 && b[0] == "0" && b[1] != ".") b = b[1..-1]
return b
}
 
// for balanced number systems only
var bCarry = Fn.new { |digit, base, idx, n, alphabet|
var carry = getCarry.call(digit, base)
if (carry != 0) {
for (i in Stepped.descend(idx..1)) {
if (n[i-1] != ".") {
var k = alphabet.indexOf(n[i-1]) + 1
if (k < base) {
n = Str.change(n, i-1, alphabet[k])
break
}
n = Str.change(n, i-1, alphabet[0])
}
}
digit = digit - base * carry
}
return [digit, n]
}
 
// convert a string from alphabet to alphabet2
var b2b // recursive function
b2b = Fn.new { |n, alphabet, alphabet2|
var res = "0"
var m = ""
if (n != "0") {
var base = alphabet.count
var base2 = alphabet2.count
var zdx = alphabet.indexOf("0") + 1
var zdx2 = alphabet2.indexOf("0") + 1
var carry = 0
var q = 0
var r = 0
var digit = 0
var idx = alphabet.indexOf(n[0]) + 1
var negative = (zdx == 1 && n[0] == "-") || (zdx != 1 && idx < zdx)
if (negative) n = negate.call(n, alphabet)
var ndp = n.indexOf(".") + 1
if (ndp != 0) {
var t = n
n = n[0...ndp-1]
m = t[ndp..-1]
}
res = ""
while (n.count > 0) {
q = 0
for (i in Stepped.ascend(1..n.count)) {
digit = alphabet.indexOf(n[i-1]) + 1 - zdx
q = q*base + digit
r = q.abs % base2
digit = (q.abs/base2).floor + zdx
if (q < 0) digit = digit - 1
if (zdx != 1) {
var p = bCarry.call(digit, base, i-1, n, alphabet)
digit = p[0]
n = p[1]
}
n = Str.change(n, i-1, alphabet[digit-1])
q = r
}
r = r + zdx2
if (zdx2 != 1) {
r = r + carry
carry = getCarry.call(r, base2)
r = r - base2 * carry
}
res = Str.insert(res, 0, alphabet2[r-1])
n = n.trimStart("0")
}
if (carry != 0) res = Str.insert(res, 0, alphabet2[carry+zdx2-1])
if (m.count > 0) {
res = res + "."
ndp = 0
if (zdx != 1) {
var lm = m.count
var alphaNew = base37[0...alphabet.count]
m = b2b.call(m, alphabet, alphaNew)
m = ("0" * (lm-m.count)) + m
alphabet = alphaNew
zdx = 1
}
while (m.count > 0 && ndp < maxdp) {
q = 0
for (i in Stepped.descend(m.count..1)) {
digit = alphabet.indexOf(m[i-1]) + 1 - zdx
q = q + digit * base2
r = q.abs % base + zdx
q = (q / base).truncate
if (q < 0) q = q - 1
m = Str.change(m, i-1, alphabet[r-1])
}
digit = q + zdx2
if (zdx2 != 1) {
var p = bCarry.call(digit, base2, res.count, res, alphabet2)
digit = p[0]
res = p[1]
}
res = res + alphabet2[digit-1]
m = m.trimEnd("0")
ndp = ndp + 1
}
}
res = bTrim.call(res)
if (negative) res = negate.call(res, alphabet2)
}
return res
}
 
// convert 'd' to a string in the specified base
var float2b = Fn.new { |d, alphabet|
var base = alphabet.count
var zdx = alphabet.indexOf("0") + 1
var carry = 0
var neg = d < 0
if (neg) d = -d
var res = ""
var whole = d.floor
d = d - whole
while (true) {
var ch = whole % base + zdx
if (zdx != 1) {
ch = ch + carry
carry = getCarry.call(ch, base)
ch = ch - base * carry
}
res = Str.insert(res, 0, alphabet[ch-1])
whole = (whole / base).truncate
if (whole == 0) break
}
if (carry != 0) {
res = Str.insert(res, 0, alphabet[carry+zdx-1])
carry = 0
}
if (d != 0) {
res = res + "."
var ndp = 0
while (d != 0 && ndp < maxdp) {
d = d * base
var digit = d.truncate + zdx
d = d - digit
if (zdx != 1) {
var p = bCarry.call(digit, base, res.count, res, alphabet)
digit = p[0]
res = p[1]
}
res = res + alphabet[digit-1]
ndp = ndp + 1
}
}
if (neg) res = negate.call(res, alphabet)
return res
}
 
var bSub // forwward declaration
 
var bAdd = Fn.new { |a, b, alphabet|
var base = alphabet.count
var zdx = alphabet.indexOf("0") + 1
var carry = 0
var da = 0
var db = 0
var digit = 0
if (zdx == 1) {
if (a[0] == "-") {
return bSub.call(b, negate.call(a, alphabet), alphabet)
}
if (b[0] == "-") {
return bSub.call(a, negate.call(b, alphabet), alphabet)
}
}
var adt = a.indexOf(".") + 1
var bdt = b.indexOf(".") + 1
if (adt != 0 || bdt != 0) {
if (adt != 0) {
adt = a.count - adt + 1
var wi = wIndex.call(-adt, a.count)
a = Str.delete(a, wi)
}
if (bdt != 0) {
bdt = b.count - bdt + 1
var wi = wIndex.call(-bdt, b.count)
b = Str.delete(b, wi)
}
if (bdt > adt) {
a = a + ("0" * (bdt-adt))
adt = bdt
} else if (adt > bdt) {
b = b + ("0" * (adt-bdt))
}
}
if (a.count < b.count) {
var t = a
a = b
b = t
}
for (i in Stepped.descend(-1..-a.count)) {
if (i < -a.count) {
da = 0
} else {
da = alphabet.indexOf(a[a.count + i]) + 1 - zdx
}
if (i < -b.count) {
db = 0
} else {
db = alphabet.indexOf(b[b.count + i]) + 1 - zdx
}
digit = da + db + carry + zdx
carry = getCarry.call(digit, base)
a = Str.change(a, i + a.count, alphabet[digit-carry*base-1])
if (i < -b.count && carry == 0) break
}
if (carry != 0) {
a = Str.insert(a, 0, alphabet[carry+zdx-1])
}
if (adt != 0) {
var wi = wIndex.call(-adt+1, a.count)
a = Str.insert(a, wi, ".")
}
a = bTrim.call(a)
return a
}
 
var aSmaller = Fn.new { |a, b, alphabet|
if (a.count != b.count) Fiber.abort("strings should be equal in length")
for (i in Stepped.ascend(1..a.count)) {
var da = alphabet.indexOf(a[i-1]) + 1
var db = alphabet.indexof(b[i-1]) + 1
if (da != db) return da < db
}
return false
}
 
// declared earlier
bSub = Fn.new { |a, b, alphabet|
var base = alphabet.count
var zdx = alphabet.indexOf("0") + 1
var carry = 0
var da = 0
var db = 0
var digit = 0
if (zdx == 1) {
if (a[0] == "-") {
return negate.call(bAdd.call(negate.call(a, alphabet), b, alphabet), alphabet)
}
if (b[0] == "-") {
return bAdd.call(a, negate.call(b, alphabet), alphabet)
}
}
var adt = a.indexOf(".") + 1
var bdt = b.indexOf(".") + 1
if (adt != 0 || bdt != 0) {
if (adt != 0) {
adt = a.count - adt + 1
var wi = wIndex.call(-adt, a.count)
a = Str.delete(a, wi)
}
if (bdt != 0) {
bdt = b.count - bdt + 1
var wi = wIndex.call(-bdt, b.count)
b = Str.delete(b, wi)
}
if (bdt > adt) {
a = a + ("0" * (bdt-adt))
adt = bdt
} else if (adt > bdt) {
b = b + ("0" * (adt-bdt))
}
}
var bNegate = false
if (a.count < b.count || (a.count == b.count && aSmaller.call(a, b, alphabet))) {
bNegate = true
var t = a
a = b
b = t
}
for (i in Stepped.descend(-1..-a.count)) {
if (i < -a.count) {
da = 0
} else {
da = alphabet.indexOf(a[a.count+i]) + 1 - zdx
}
if (i < -b.count) {
db = 0
} else {
db = alphabet.indexOf(b[b.count+i]) + 1 - zdx
}
digit = da - db - carry + zdx
carry = 0
if (digit <= 0) carry = 1
a = Str.change(a, i+a.count, alphabet[digit+carry*base-1])
if (i < -b.count && carry == 0) break
}
if (carry != 0) Fiber.abort("carry should be zero")
if (adt != 0) {
var wi = wIndex.call(-adt+1, a.count)
a = Str.insert(a, wi, ".")
}
a = bTrim.call(a)
if (bNegate) a = negate.call(a, alphabet)
return a
}
 
var bMul = Fn.new { |a, b, alphabet|
var zdx = alphabet.indexOf("0") + 1
var dpa = a.indexOf(".") + 1
var dpb = b.indexOf(".") + 1
var ndp = 0
if (dpa != 0) {
ndp = ndp + a.count - dpa
a = Str.delete(a, dpa-1)
}
if (dpb != 0) {
ndp = ndp + b.count - dpb
b = Str.delete(b, dpb-1)
}
var pos = a
var res = "0"
if (zdx != 1) {
// balanced number systems
var neg = negate.call(pos, alphabet)
for (i in Stepped.descend(b.count..1)) {
var m = alphabet.indexOf(b[i-1]) + 1 - zdx
while (m != 0) {
var temp = pos
var temp2 = -1
if (m < 0) {
temp = neg
temp2 = 1
}
res = bAdd.call(res, temp, alphabet)
m = m + temp2
}
pos = pos + "0"
neg = neg + "0"
}
} else {
// non-balanced number systems
var negative = false
if (a[0] == "-") {
a = a[1..-1]
negative = true
}
if (b[0] == "-") {
b = b[1..-1]
negative = !negative
}
for (i in Stepped.descend(b.count..1)) {
var m = alphabet.indexOf(b[i-1]) + 1 - zdx
while (m > 0) {
res = bAdd.call(res, pos, alphabet)
m = m - 1
}
pos = pos + "0"
}
if (negative) res = negate.call(res, alphabet)
}
if (ndp != 0) {
var wi = wIndex.call(-ndp, res.count)
res = Str.insert(res, wi, ".")
}
res = bTrim.call(res)
return res
}
 
var multTable = Fn.new {
System.print("multiplication table")
System.print("====================")
System.write("* |")
for (j in 1..12) {
Fmt.write(" #$s $3s |", float2b.call(j, hexadecimal), float2b.call(j, balancedTernary))
}
for (i in 1..27) {
var a = float2b.call(i, balancedTernary)
Fmt.write("\n$-2s|", float2b.call(i, septemVigesimal))
for (j in 1..12) {
if (j > i) {
System.write(" |")
} else {
var b = float2b.call(j, balancedTernary)
var m = bMul.call(a, b, balancedTernary)
Fmt.write(" $6s |", m)
}
}
}
System.print()
}
 
var test = Fn.new {|name, alphabet|
var a = b2b.call("+-0++0+.+-0++0+", balancedTernary, alphabet)
var b = b2b.call("-436.436", decimal, alphabet)
var c = b2b.call("+-++-.+-++-", balancedTernary, alphabet)
var d = bSub.call(b, c, alphabet)
var r = bMul.call(a, d, alphabet)
Fmt.print("$s\n$s", name, "=" * name.count)
Fmt.print(" a = $.14f $s", b2dec.call(a, alphabet), a)
Fmt.print(" b = $.14f $s", b2dec.call(b, alphabet), b)
Fmt.print(" c = $.14f $s", b2dec.call(c, alphabet), c)
Fmt.print("a*(b-c) = $.14f $s\n", b2dec.call(r, alphabet), r)
}
 
test.call("balanced ternary", balancedTernary)
test.call("balanced base 27", balancedBase27)
test.call("decimal", decimal)
test.call("binary", binary)
test.call("ternary", ternary)
test.call("hexadecimal", hexadecimal)
test.call("septemvigesimal", septemVigesimal)
multTable.call()</syntaxhighlight>
 
{{out}}
<pre>
balanced ternary
================
a = 523.23914037494285 +-0++0+.+-0++0+
b = -436.43599999999992 -++-0--.--0+-00+++-0-+---0-+0++++0--0000+00-+-+--+0-0-00--++0-+00---+0+-+++0+-0----0++
c = 65.26748971193416 +-++-.+-++-
a*(b-c) = -262510.90267998125637 ----000-0+0+.0+0-0-00---00--0-0+--+--00-0++-000++0-000-+0+-----+++-+-0+-+0+0++0+0-++-++0+---00++++
 
balanced base 27
================
a = 523.23914037494285 AUJ.FLI
b = -436.43600000000004 NKQ.YFDFTYSMHVANGXPVXHIZJRJWZD0PBGFJAEBAKOZODLY0ITEHPQLSQSGLFZUINATKCIKUVMWEWJMQ0COTS
c = 65.26748971193416 BK.GF
a*(b-c) = -262510.90267998125637 ZVPJ.CWNYQPEENDVDPNJZXKFGCLHKLCX0YIBOMETHFWWBTVUFAH0SEZMTBJDCRRAQIQCAWMKXSTPYUXYPK0LODUO
 
decimal
=======
a = 523.23914037494296 523.239140374942844078646547782350251486053955189757658893461362597165066300868770004
b = -436.43599999999998 -436.436
c = 65.26748971193415 65.267489711934156378600823045267489711934156378600823045267489711934156378600823045
a*(b-c) = -262510.90267998137278 -262510.90267998140903693918986303277315826215892262734715612833785876513103053772667101895163734826631742752252837097627017862754285047634638652268078676654605120794218
 
binary
======
a = 523.23914037494274 1000001011.001111010011100001001101101110011000100001011110100101001010100100000111001000111
b = -436.43600000000004 -110110100.011011111001110110110010001011010000111001010110000001000001100010010011011101001
c = 65.26748971193416 1000001.01000100011110100011010010101100110001100000111010111111101111001001001101111101
a*(b-c) = -262510.90267998143099 -1000000000101101110.111001110001011000001001000001101110011111011100000100000100001000101011100011110010110001010100110111001011101001010000001110110100111110001101000000001111110101
 
ternary
=======
a = 523.23914037494285 201101.0201101
b = -436.43600000000021 -121011.102202211210021110012111201022222000202102010100101200200110122011122101110212
c = 65.26748971193416 2102.02102
a*(b-c) = -262510.90267998125637 -111100002121.2201010011100110022102110002120222120100001221111011202022012121122001201122110221112
 
hexadecimal
===========
a = 523.23914037494274 20B.3D384DB9885E94A90723EF9CBCB174B443E45FFC41152FE0293416F15E3AC303A0F3799ED81589C62
b = -436.43599999999998 -1B4.6F9DB22D0E5604189374BC6A7EF9DB22D0E5604189374BC6A7EF9DB22D0E5604189374BC6A7EF9DB2
c = 65.26748971193416 41.447A34ACC60EBFBC937D5DC2E5A99CF8A021B641511E8D2B3183AFEF24DF5770B96A673E28086D905
a*(b-c) = -262510.90267998143099 -4016E.E7160906E7DC10422DA508321819F4A637E5AEE668ED5163B12FCB17A732442F589975B7F24112B2E8F6E95EAD45803915EE26D20DF323D67CAEEC75D7BED68AA34E02F2B492257D66F028545FB398F60E
 
septemvigesimal
===============
a = 523.23914037494285 JA.6C9
b = -436.43600000000004 -G4.BKML7C5DJ8Q0KB39AIICH4HACN02OJKGPLOPG2D1MFBQI6LJ33F645JELD7I0Q6FNHG88E9M9GE3QO276
c = 65.26748971193416 2B.76
a*(b-c) = -262510.90267998125637 -D92G.OA1C42LM0N8N30HDAFKJNEIFEOB0BHP1DM6ILA9P797KPJ05MCE6OGMO54Q3I3NQ9DGB673C8BC2FQF1N82
 
multiplication table
====================
* | #1 + | #2 +- | #3 +0 | #4 ++ | #5 +-- | #6 +-0 | #7 +-+ | #8 +0- | #9 +00 | #A +0+ | #B ++- | #C ++0 |
1 | + | | | | | | | | | | | |
2 | +- | ++ | | | | | | | | | | |
3 | +0 | +-0 | +00 | | | | | | | | | |
4 | ++ | +0- | ++0 | +--+ | | | | | | | | |
5 | +-- | +0+ | +--0 | +-+- | +0-+ | | | | | | | |
6 | +-0 | ++0 | +-00 | +0-0 | +0+0 | ++00 | | | | | | |
7 | +-+ | +--- | +-+0 | +00+ | ++0- | +---0 | +--++ | | | | | |
8 | +0- | +--+ | +0-0 | ++-- | ++++ | +--+0 | +-0+- | +-+0+ | | | | |
9 | +00 | +-00 | +000 | ++00 | +--00 | +-000 | +-+00 | +0-00 | +0000 | | | |
A | +0+ | +-+- | +0+0 | ++++ | +-0-- | +-+-0 | +0--+ | +000- | +0+00 | ++-0+ | | |
B | ++- | +-++ | ++-0 | +--0- | +-00+ | +-++0 | +00-- | +0+-+ | ++-00 | ++0+- | +++++ | |
C | ++0 | +0-0 | ++00 | +--+0 | +-+-0 | +0-00 | +00+0 | ++--0 | ++000 | ++++0 | +--0-0 | +--+00 |
D | +++ | +00- | +++0 | +-0-+ | +-++- | +00-0 | +0+0+ | ++0-- | +++00 | +---++ | +--+0- | +-0-+0 |
E | +--- | +00+ | +---0 | +-0+- | +0--+ | +00+0 | ++-0- | ++0++ | +---00 | +--+-- | +-0-0+ | +-0+-0 |
F | +--0 | +0+0 | +--00 | +-+-0 | +0-+0 | +0+00 | ++0-0 | ++++0 | +--000 | +-0--0 | +-00+0 | +-+-00 |
G | +--+ | ++-- | +--+0 | +-+0+ | +000- | ++--0 | ++0++ | +---+- | +--+00 | +-00-+ | +-+--- | +-+0+0 |
H | +-0- | ++-+ | +-0-0 | +0--- | +00++ | ++-+0 | ++++- | +--00+ | +-0-00 | +-0+0- | +-+0-+ | +0---0 |
I | +-00 | ++00 | +-000 | +0-00 | +0+00 | ++000 | +---00 | +--+00 | +-0000 | +-+-00 | +-++00 | +0-000 |
J | +-0+ | +++- | +-0+0 | +0-++ | ++--- | +++-0 | +--0-+ | +-0-0- | +-0+00 | +-+00+ | +0--+- | +0-++0 |
K | +-+- | ++++ | +-+-0 | +000- | ++-0+ | ++++0 | +--+-- | +-00-+ | +-+-00 | +-+++- | +0-0++ | +000-0 |
L | +-+0 | +---0 | +-+00 | +00+0 | ++0-0 | +---00 | +--++0 | +-0+-0 | +-+000 | +0--+0 | +00--0 | +00+00 |
M | +-++ | +--0- | +-++0 | +0+-+ | ++0+- | +--0-0 | +-0-0+ | +-+--- | +-++00 | +0-0++ | +0000- | +0+-+0 |
N | +0-- | +--0+ | +0--0 | +0++- | +++-+ | +--0+0 | +-000- | +-+-++ | +0--00 | +00--- | +00+0+ | +0++-0 |
O | +0-0 | +--+0 | +0-00 | ++--0 | ++++0 | +--+00 | +-0+-0 | +-+0+0 | +0-000 | +000-0 | +0+-+0 | ++--00 |
P | +0-+ | +-0-- | +0-+0 | ++-0+ | +---0- | +-0--0 | +-0+++ | +-+++- | +0-+00 | +00+-+ | +0++-- | ++-0+0 |
Q | +00- | +-0-+ | +00-0 | ++0-- | +---++ | +-0-+0 | +-+-+- | +0--0+ | +00-00 | +0+-0- | ++---+ | ++0--0 |
10| +000 | +-000 | +0000 | ++000 | +--000 | +-0000 | +-+000 | +0-000 | +00000 | +0+000 | ++-000 | ++0000 |
</pre>
 
[[Category:Arbitrary precision]]
9,482

edits