.
Code: Select all
; -- Radix Conversion 2.11
; tested with PB 5.24 LTS, 5.31 (x86 and x64) on Windows
; <http://www.purebasic.fr/english/viewtopic.php?f=12&t=55799>
;
; _ConvertNumber() and related functions extended after
; <http://jonnydee.wordpress.com/2011/05/01/convert-a-block-of-digits-from-base-x-to-base-y/>, access on 2015-01-01
DeclareModule Radi
EnableExplicit
#StdSymbols$ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
; -- optional utility functions
Declare.i NumDigits (number.q, base.i)
Declare.i MaxDestDigits (srcLen.i, srcBase.i, destBase.i)
Declare.i UniqueSymbols (symbols$)
; -- similar to PB's Val() and Str(), but for any base >= 2
Declare.q ValB (number$, srcBase.i, srcSymbols$=#StdSymbols$)
Declare.s StrB (number.q, destBase.i, groupSize.i=0, destSymbols$=#StdSymbols$)
; -- combination of ValB() and StrB(), even for big numbers
Declare.s Vast (source$, srcBase.i, destBase.i, groupSize.i=0, srcSymbols$=#StdSymbols$, destSymbols$=#StdSymbols$)
; -- some wrappers of Vast()
Macro Dec2Hex (_dec_, _groupSize_=0)
Radi::Vast(_dec_, 10, 16, _groupSize_)
EndMacro
Macro Hex2Dec (_hex_, _groupSize_=3)
Radi::Vast(UCase(_hex_), 16, 10, _groupSize_)
EndMacro
Macro Dec2Bin (_dec_, _groupSize_=4)
Radi::Vast(_dec_, 10, 2, _groupSize_)
EndMacro
Macro Bin2Dec (_bin_, _groupSize_=3)
Radi::Vast(_bin_, 2, 10, _groupSize_)
EndMacro
Macro Dec2Sex (_dec_)
Radi::Vast(_dec_, 10, 60, -1)
EndMacro
Macro Sex2Dec (_sex_, _groupSize_=3)
Radi::Vast(_sex_, 60, 10, _groupSize_, "")
EndMacro
; -- balanced ternary, even for big numbers
Declare.s Any2Bt (source$, srcBase.i, groupSize.i=0, srcSymbols$=#StdSymbols$)
Declare.s Bt2Any (source$, destBase.i, groupSize.i=0, destSymbols$=#StdSymbols$)
EndDeclareModule
Module Radi
Structure CharArray
char.c[0]
EndStructure
#SignSymbols$ = "-+"
#ListLeft$ = "{"
#ListRight$ = "}"
#ListDelim$ = ","
#GroupDelim$ = " "
#BtSymbols$ = "T01"
Procedure.i NumDigits (n.q, base.i)
; in : n : whole number >= 0
; base: whole number >= 2
; out: return value: number of digits that 'n' has,
; when represented with base 'base'
If n < 0 Or base < 2
ProcedureReturn 0 ; error
ElseIf n > 0
ProcedureReturn Round(Log(n) / Log(base), #PB_Round_Down) + 1
Else
ProcedureReturn 1
EndIf
EndProcedure
Procedure.i MaxDestDigits (srcLen.i, srcBase.i, destBase.i)
; in : srcLen : number of digits that a given number has when expressed with
; base 'srcBase' in a standard positional numeral system
; srcBase : base of given number (>= 2)
; destBase: destination base (>= 2)
; out: return value: maximum number of digits needed for expressing the number with
; base 'destBase' in a standard positional numeral system,
; or 0 on error
If srcBase < 2 Or destBase < 2
ProcedureReturn 0 ; error
Else
ProcedureReturn Round(srcLen * Log(srcBase) / Log(destBase), #PB_Round_Up)
EndIf
EndProcedure
Procedure.i UniqueSymbols (symbols$)
; in : list of symbols, as used by ValB(), StrB(), Vast(), Any2Bt(), and Bt2Any()
; out: return value: #False if 'symbols$' contains duplicate characters,
; #True otherwise
Protected i.i, symbolsLen.i=Len(symbols$)
Protected *sym.CharArray = @ symbols$
For i = 2 To symbolsLen
If FindString(symbols$, Chr(*sym\char[i-2]), i)
ProcedureReturn #False
EndIf
Next
ProcedureReturn #True
EndProcedure
Procedure.s _Groups (s$, groupSize.i, delim$)
; -- partition 's$' by inserting 'delim$'
Protected i.i=Len(s$)
While i > groupSize
i - groupSize
s$ = InsertString(s$, delim$, i+1)
Wend
ProcedureReturn s$
EndProcedure
Macro _ValPrepareSource
; used in ValB() and _ValDigits()
If srcBase < 2
ProcedureReturn 0 ; error
EndIf
srcSymbols$ = Left(srcSymbols$, srcBase)
left = FindString(source$, #ListLeft$)
right = FindString(source$, #ListRight$)
If (left And right) And
(FindString(srcSymbols$, #ListLeft$) = 0 And
FindString(srcSymbols$, #ListRight$) = 0)
srcSymbolsLen = 0
Else
srcSymbolsLen = Len(srcSymbols$)
EndIf
If srcSymbolsLen > 0
If srcSymbolsLen < srcBase
ProcedureReturn 0 ; error
EndIf
sign$ = Left(source$, 1)
If FindString(srcSymbols$, sign$) = 0
sign = FindString(#SignSymbols$, sign$)
If sign > 0
source$ = Mid(source$, 2)
EndIf
EndIf
If FindString(srcSymbols$, #GroupDelim$) = 0
source$ = RemoveString(source$, #GroupDelim$)
EndIf
Else
sign$ = Trim(Left(source$, left-1))
sign = FindString(#SignSymbols$, sign$)
source$ = Mid(source$, left+1, right-left-1)
EndIf
If sign > 0 And offset < 0
ProcedureReturn 0 ; error
EndIf
srcLen = Len(source$)
If srcLen = 0
ProcedureReturn 0 ; error
ElseIf srcSymbolsLen = 0
srcLen = CountString(source$, #ListDelim$) + 1
EndIf
EndMacro
Procedure.q ValB (source$, srcBase.i, srcSymbols$=#StdSymbols$)
; -- convert 'source$' from string representation with base 'srcBase' to a quad
; in : see elaborate description of parameters at Vast()
; out: return value: value of 'source$',
; or 0 on error
Protected i.i, digit.i, sign.i=0, sign$="", ret.q=0
Protected *src.CharArray, srcLen.i, srcSymbolsLen.i
Protected left.i, right.i, offset.i
_ValPrepareSource
If srcSymbolsLen > 0
*src = @ source$
For i = 1 To srcLen
digit = FindString(srcSymbols$, Chr(*src\char[i-1])) - 1
If digit < 0
ProcedureReturn 0 ; error
EndIf
ret * srcBase + digit
Next
Else
For i = 1 To srcLen
digit = Val(StringField(source$, i, #ListDelim$))
If digit < 0 Or digit >= srcBase
ProcedureReturn 0 ; error
EndIf
ret * srcBase + digit
Next
EndIf
If ret < 0
ret = 0 ; error: overflow
ElseIf sign = 1 ; 1 means negative
ret = -ret
EndIf
ProcedureReturn ret
EndProcedure
Procedure.s StrB (number.q, destBase.i, groupSize.i=0, destSymbols$=#StdSymbols$)
; -- convert 'number' to a string representation with base 'destBase'
; For details about input parameters and return value see elaborate description at Vast().
Protected digit.i, sign$="", ret$
Protected *destSymbols.CharArray, destSymbolsLen.i=Len(destSymbols$)
If destBase < 2
ProcedureReturn "" ; error
EndIf
If groupSize < 0 Or destSymbolsLen < destBase
destSymbolsLen = 0
EndIf
If number < 0
sign$ = Left(#SignSymbols$, 1)
number = -number
EndIf
If destSymbolsLen > 0
*destSymbols = @ destSymbols$
ret$ = ""
Repeat
digit = number % destBase
ret$ = Chr(*destSymbols\char[digit]) + ret$
number / destBase
Until number = 0
If groupSize > 0 And FindString(destSymbols$, #GroupDelim$) = 0
ret$ = _Groups(ret$, groupSize, #GroupDelim$)
EndIf
ProcedureReturn sign$ + ret$
Else
digit = number % destBase
ret$ = Str(digit)
number / destBase
While number <> 0
digit = number % destBase
ret$ = Str(digit) + #ListDelim$ + ret$
number / destBase
Wend
ProcedureReturn sign$ + #ListLeft$ + ret$ + #ListRight$
EndIf
EndProcedure
Procedure.i _ValDigits (source$, srcBase.i, srcSymbols$, Array srcDigits.i(1), offset.i=0)
; -- convert 'source$' from string representation with base 'srcBase' to an array of digits
; (array element 0 is reserved for the sign)
; returns 1 on success, 0 on error
Protected i.i, digit.i, sign.i=0, sign$=""
Protected *src.CharArray, srcLen.i, srcSymbolsLen.i
Protected left.i, right.i
_ValPrepareSource
Dim srcDigits.i(srcLen)
srcDigits(0) = sign ; 1 means negative
If srcSymbolsLen > 0
*src = @ source$
For i = 1 To srcLen
digit = FindString(srcSymbols$, Chr(*src\char[i-1])) - 1 + offset
If digit < offset
ProcedureReturn 0 ; error
EndIf
srcDigits(i) = digit
Next
Else
For i = 1 To srcLen
digit = Val(StringField(source$, i, #ListDelim$))
If digit < offset Or digit >= srcBase + offset
ProcedureReturn 0 ; error
EndIf
srcDigits(i) = digit
Next
EndIf
ProcedureReturn 1 ; success
EndProcedure
Procedure.s _StrDigits (Array destDigits.i(1), destBase.i, groupSize.i, destSymbols$, offset.i=0)
; -- convert array of digits with base 'destBase' to a string representation
; (array element 0 is reserved for the sign)
; 'destBase' is always >= 2
Protected msd.i, i.i, sign$="", ret$, destLen.i=ArraySize(destDigits())
Protected *destSymbols.CharArray, destSymbolsLen.i=Len(destSymbols$)
If groupSize < 0 Or destSymbolsLen < destBase
destSymbolsLen = 0
EndIf
If destDigits(0) = 1 ; 1 means negative
sign$ = Left(#SignSymbols$, 1)
EndIf
msd = 1 ; first index behind the sign
While destDigits(msd) = 0 And msd < destLen
msd + 1 ; skip leading zeros
Wend
If destSymbolsLen > 0
*destSymbols = @ destSymbols$
ret$ = ""
For i = msd To destLen
ret$ + Chr(*destSymbols\char[destDigits(i)-offset])
Next
If groupSize > 0 And FindString(destSymbols$, #GroupDelim$) = 0
ret$ = _Groups(ret$, groupSize, #GroupDelim$)
EndIf
ProcedureReturn sign$ + ret$
Else
ret$ = Str(destDigits(msd))
For i = msd+1 To destLen
ret$ + #ListDelim$ + Str(destDigits(i))
Next
ProcedureReturn sign$ + #ListLeft$ + ret$ + #ListRight$
EndIf
EndProcedure
;--------------------------------------------------------------------
Procedure _NegNumber (Array digits.i(1))
; -- negation of each element in 'digits()'
Protected i.i
For i = ArraySize(digits()) To 1 Step -1
digits(i) = -digits(i)
Next
EndProcedure
Procedure _IncDigitsByValue (Array digits.i(1), msd.i, value.i, base.i)
; -- increment each element of 'digits()' in the given range by 'value',
; using radix-'base' arithmetic
Protected tmp.q, i.i, carry.i=0
For i = ArraySize(digits()) To 1 Step -1 ; Array element 0 is reserved for the sign.
If i >= msd
carry + value
ElseIf carry = 0
Break
EndIf
tmp = digits(i) + carry
digits(i) = tmp % base
carry = tmp / base
Next
EndProcedure
Procedure _IncNumberByValue (Array digits.i(1), value.i, base.i)
; -- increment 'digits()' by 'value', using radix-'base' arithmetic
Protected tmp.q, i.i, carry.i=value
For i = ArraySize(digits()) To 1 Step -1 ; Array element 0 is reserved for the sign.
If carry = 0
Break
EndIf
tmp = digits(i) + carry
digits(i) = tmp % base
carry = tmp / base
If digits(i) < 0
digits(i) + base
carry - 1
EndIf
Next
EndProcedure
Procedure _MultNumberByValue (Array digits.i(1), value.i, base.i)
; -- multiply 'digits()' by 'value', using radix-'base' arithmetic
Protected tmp.q, i.i, carry.i=0
For i = ArraySize(digits()) To 1 Step -1 ; Array element 0 is reserved for the sign.
tmp = digits(i) * value + carry ; Very big source and destination bases can cause an overflow here.
digits(i) = tmp % base
carry = tmp / base
Next
EndProcedure
Procedure.i _ConvertNumber (Array srcDigits.i(1), srcBase.i, Array destDigits.i(1), destBase.i)
; -- convert source digits to destination digits
; returns 1 on success, 0 on error
Protected i.i, destLen.i, srcLen.i=ArraySize(srcDigits())
destLen = MaxDestDigits(srcLen, srcBase, destBase)
If destLen = 0
ProcedureReturn 0 ; error
Else
Dim destDigits(destLen+1) ; set sufficient array size
EndIf ; (+1 is needed for Any2Bt())
; -- do conversion
_IncNumberByValue(destDigits(), srcDigits(1), destBase)
For i = 2 To srcLen
_MultNumberByValue(destDigits(), srcBase, destBase)
_IncNumberByValue (destDigits(), srcDigits(i), destBase)
Next
destDigits(0) = srcDigits(0) ; copy the sign
ProcedureReturn 1 ; success
EndProcedure
;--------------------------------------------------------------------
Procedure.s Vast (source$, srcBase.i, destBase.i, groupSize.i=0, srcSymbols$=#StdSymbols$, destSymbols$=#StdSymbols$)
; -- combination of ValB() and StrB() for numbers of (almost) arbitrary size;
; converts a whole number from any integer base >= 2 to any integer base >= 2
; (On 32 bit systems, both bases can be as big as the largest positive signed integer value (> 2*10^9).
; On 64 bit systems, both bases can be even > 3*10^9.)
; in : source$ : string that represents a whole number (may have a leading '+' or '-'),
; given in one of the following formats:
; (a) list of characters that are contained in 'srcSymbols$'
; (optionally including '#GroupDelim$' at any positions
; for cosmetic reasons), e.g.
; 1101 0010
; -FF
; (b) list of decimal numbers, surrounded by '#ListLeft$' and
; '#ListRight$', and separated by '#ListDelim$', e.g.
; {200,31,17,5,124}
; -{4,15,9}
; A number in this format can only be recognized correctly if
; 'srcSymbols$' does not contain '#ListLeft$' or '#ListRight$'.
; srcBase : base of 'source$'
; destBase : destination base
; groupSize : If 'groupSize' is > 0 and 'destSymbols$' is not empty, then for
; pure cosmetic reasons the returned string will be partitioned from
; right to left into groups of 'groupSize' symbols, separated by
; '#GroupDelim$' (unless '#GroupDelim$' is contained in 'destSymbols$').
; srcSymbols$ : list of unique characters;
; The first 'srcBase' characters of the list are allowed in 'source$'
; of format (a).
; destSymbols$: list of unique characters;
; The first 'destBase' characters of the list are allowed for
; building a destination number of format (a).
; The values of the symbols in 'srcSymbols$' and 'destSymbols$' are 0,1,2,...,
; increasing from left to right.
; Note: If 'srcSymbols$' or 'destSymbols$' contain any non-ASCII characters,
; be sure to compile your program in Unicode mode!
; out: return value: 'source$' expressed with 'destBase' (may have a leading '-'),
; in one of the following formats:
; (a) If 'groupSize' is >= 0 and 'destSymbols$' has at least 'destBase'
; characters, then the return value will be a list of characters
; that are contained in 'destSymbols$' (optionally separated by
; '#GroupDelim$'), e.g.
; 1101 0010
; -FF
; (b) Otherwise it will be a list of decimal numbers, surrounded by
; '#ListLeft$' and '#ListRight$', and separated by '#ListDelim$', e.g.
; {200,31,17,5,124}
; -{4,15,9}
; For human readers, this format is especially useful if 'destBase'
; is rather big, so they don't have to memorize the meaning of many
; symbols.
; or "" on error
Protected Dim srcDigits.i(0)
Protected Dim destDigits.i(0)
If _ValDigits(source$, srcBase, srcSymbols$, srcDigits())
If _ConvertNumber(srcDigits(), srcBase, destDigits(), destBase)
ProcedureReturn _StrDigits(destDigits(), destBase, groupSize, destSymbols$)
EndIf
EndIf
ProcedureReturn "" ; error
EndProcedure
Procedure.s Any2Bt (source$, srcBase.i, groupSize.i=0, srcSymbols$=#StdSymbols$)
; -- convert even a big whole standard number with any integer base >= 2 to a "balanced ternary" number
; Balanced ternary is a non-standard positional numeral system with base 3,
; using the digits -1, 0, and 1. Balanced ternary numbers do not have an explicit
; sign, but it is implicitly given by the most significant (= leftmost) nonzero digit.
; (see also http://en.wikipedia.org/wiki/Balanced_ternary)
; [code according to Knuth: TAOCP Vol. 2, 3rd ed. 1997, p. 207]
;
; For details about input parameters and return value see elaborate description at Vast().
Protected msd.i, i.i, destLen.i
Protected Dim srcDigits.i(0)
Protected Dim destDigits.i(0)
If _ValDigits(source$, srcBase, srcSymbols$, srcDigits())
If _ConvertNumber(srcDigits(), srcBase, destDigits(), 3) ; initially, convert to standard base 3 number
destLen = ArraySize(destDigits())
msd = 1 ; first index behind the sign
While destDigits(msd) = 0 And msd < destLen
msd + 1 ; skip leading zeros
Wend
_IncDigitsByValue(destDigits(), msd, 1, 3)
For i = msd To destLen
destDigits(i) - 1
Next
If destDigits(0) = 1 ; 1 means negative
destDigits(0) = 0
_NegNumber(destDigits())
EndIf
ProcedureReturn _StrDigits(destDigits(), 3, groupSize, #BtSymbols$, -1)
EndIf
EndIf
ProcedureReturn "" ; error
EndProcedure
Procedure.s Bt2Any (source$, destBase.i, groupSize.i=0, destSymbols$=#StdSymbols$)
; -- convert even a big whole "balanced ternary" number to a standard number with any integer base >= 2
; [code according to Knuth: TAOCP Vol. 2, 3rd ed. 1997, p. 207]
;
; For details about input parameters and return value see elaborate description at Vast().
Protected msd.i, srcLen.i
Protected Dim srcDigits.i(0)
Protected Dim destDigits.i(0)
If _ValDigits(source$, 3, #BtSymbols$, srcDigits(), -1)
srcLen = ArraySize(srcDigits())
msd = 1 ; first index behind the sign
While srcDigits(msd) = 0 And msd < srcLen
msd + 1 ; skip leading zeros
Wend
If srcDigits(msd) < 0
srcDigits(0) = 1 ; 1 means negative
_NegNumber(srcDigits())
EndIf
If _ConvertNumber(srcDigits(), 3, destDigits(), destBase)
ProcedureReturn _StrDigits(destDigits(), destBase, groupSize, destSymbols$)
EndIf
EndIf
ProcedureReturn "" ; error
EndProcedure
EndModule
CompilerIf #PB_Compiler_IsMainFile
; * Module demo *
EnableExplicit
Define n.i, src$, dest.q, dest$, symbols$
Macro Demo_NumDigits (_number_, _base_)
n = Radi::NumDigits(_number_, _base_)
Debug "When represented with base " + _base_ + ", the decimal number " + _number_ + " has " + n + " digit(s)."
EndMacro
Macro Demo_MaxDestDigits (_srcLen_, _srcBase_, _destBase_)
n = Radi::MaxDestDigits(_srcLen_, _srcBase_, _destBase_)
Debug "A number that has " + _srcLen_ + " digits when expressed with base " + _srcBase_
Debug " has at most " + n + " digits when expressed with base " + _destBase_ + "."
EndMacro
Macro Demo_UniqueSymbols (_symbols_)
n = Radi::UniqueSymbols(_symbols_)
Debug "UniqueSymbols(" + #DQUOTE$ + _symbols_ + #DQUOTE$ + ") = " + n
EndMacro
Macro Demo_ValB (_number_, _srcBase_, _srcSymbols_=Radi::#StdSymbols$)
dest = Radi::ValB(_number_, _srcBase_, _srcSymbols_)
Debug "ValB(" + #DQUOTE$ + _number_ + #DQUOTE$ + ", " + _srcBase_ + ") = " + dest
EndMacro
Macro Demo_StrB (_number_, _destBase_, _groupSize_=0, _destSymbols_=Radi::#StdSymbols$)
dest$ = Radi::StrB(_number_, _destBase_, _groupSize_, _destSymbols_)
Debug "StrB(" + _number_ + ", " + _destBase_ + ") = " + #DQUOTE$ + dest$ + #DQUOTE$
EndMacro
Macro Demo_Vast (_number_, _srcBase_, _destBase_, _groupSize_=0, _srcSymbols_=Radi::#StdSymbols$, _destSymbols_=Radi::#StdSymbols$)
dest$ = Radi::Vast(_number_, _srcBase_, _destBase_, _groupSize_, _srcSymbols_, _destSymbols_)
Debug " base " + _srcBase_ + ": " + _number_
Debug "-> base " + _destBase_ + ": " + dest$
Debug ""
EndMacro
Macro Demo_Any2Bt (_number_, _srcBase_, _groupSize_=0, _srcSymbols_=Radi::#StdSymbols$)
dest$ = Radi::Any2Bt(_number_, _srcBase_, _groupSize_, _srcSymbols_)
Debug "Any2Bt(" + #DQUOTE$ + _number_ + #DQUOTE$ + ", " + _srcBase_ + ") = " + dest$
EndMacro
Macro Demo_Bt2Any (_number_, _destBase_, _groupSize_=0, _destSymbols_=Radi::#StdSymbols$)
dest$ = Radi::Bt2Any(_number_, _destBase_, _groupSize_, _destSymbols_)
Debug "Bt2Any(" + #DQUOTE$ + _number_ + #DQUOTE$ + ", " + _destBase_ + ") = " + dest$
EndMacro
;--------------------------------------------------------------------
Debug "-- NumDigits()"
Demo_NumDigits(12, 2)
Demo_NumDigits(12, 10)
Demo_NumDigits(12, 16)
Debug ""
Debug "-- MaxDestDigits()"
Demo_MaxDestDigits(154, 10, 2)
Demo_MaxDestDigits(128, 16, 2)
Demo_MaxDestDigits(160, 10, 100)
Debug ""
Debug "-- UniqueSymbols()"
Demo_UniqueSymbols("ABab")
Demo_UniqueSymbols("ABCA")
Debug ""
Debug "-- ValB()"
Demo_ValB("1111 1111", 2)
Demo_ValB("-FF" , 16)
Demo_ValB("-{15,15}" , 16)
; In contrast to PB's built-in Val() function,
; ValB() will return 0 to indicate an error,
; if the source contains any not permitted symbol:
Debug Val("$CX") ; -> 12
Debug Radi::ValB("CX", 16) ; -> 0
Debug ""
Debug "-- StrB()"
Demo_StrB(-255, 16) ; output in format (a)
Demo_StrB( 255, 2, 4) ; output in format (a) with group delimiter
Demo_StrB(-255, 16, -1) ; groupSize = -1 forces output in format (b)
Demo_StrB(1000, 60) ; format (b) is automatically chosen for output because 60 > Len(destSymbols$)
Debug ""
Debug "-- Vast()"
Demo_Vast("40 000" , 10, 16)
Demo_Vast("40 000" , 10, 16, -1)
Demo_Vast("-123456789012345678901234567890", 10, 16)
Demo_Vast("-123456789012345678901234567890", 10, 256)
Demo_Vast("9C40" , 16, 10, 3)
Demo_Vast("{9,12,4,0}", 16, 10)
Demo_Vast("9C40" , 16, 36)
Demo_Vast("9C40" , 16, 60)
Demo_Vast("{2,46,40}", 60, 10, 3)
Demo_Vast("{2,46,40}", 60, 16)
Demo_Vast("{2,46,40}", 60, 36)
src$ = "AHZ46H67JLR4KCGFWQBDYIHO"
symbols$ = "~#.^°/&!"
If Radi::UniqueSymbols(symbols$)
Debug "Using special destination symbols ..."
Demo_Vast(src$, Len(Radi::#StdSymbols$), Len(symbols$), 0, Radi::#StdSymbols$, symbols$)
Else
Debug "Error: Duplicate symbols in " + #DQUOTE$ + symbols$ + #DQUOTE$
Debug ""
EndIf
Debug "-- Dec2Sex()"
src$ = "20 000"
dest$ = Radi::Dec2Sex(src$)
Debug src$ + " (seconds)"
Debug dest$ + " (hours,minutes,seconds)"
Debug ""
Debug "-- Sex2Dec()"
src$ = dest$
dest$ = Radi::Sex2Dec(src$)
Debug src$ + " (hours,minutes,seconds)"
Debug dest$ + " (seconds)"
Debug ""
Debug "-- Any2Bt()"
Demo_Any2Bt( "8", 10)
Demo_Any2Bt( "8", 10, -1)
Demo_Any2Bt( "33", 10)
Demo_Any2Bt("-33", 10)
Debug ""
Debug "-- Bt2Any()"
Demo_Bt2Any( "10T", 10)
Demo_Bt2Any("{1,0,-1}", 10)
Demo_Bt2Any("11T0", 10)
Demo_Bt2Any("TT10", 10)
Demo_Bt2Any("+10T", 10) ; A balanced ternary number ...
Demo_Bt2Any("-10T", 10) ; ... can not have an explicit sign.
Demo_Bt2Any( "10T", 2)
CompilerEndIf