mercoledì 12 gennaio 2011

Conversione numerica da/a qualsiasi base

Riporto il codice autocostruito per NSIS al fine di eseguire delle conversioni numeriche da base decimale a qualsiasi altra base compresa tra 2 e 36.


Function DecToBX
Exch $R2 ; base
Exch
Exch $R1 ; number
Push $R0
Exch 2
Push $R3
StrCpy $R0 "" ; result

Loop:
System::Int64Op $R1 % $R2
Pop $R3

StrCpy $R3 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 1 $R3
StrCpy $R0 "$R3$R0"

System::Int64Op $R1 / $R2
Pop $R1

StrCmp $R1 0 0 Loop

Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd

!macro DecToBX Res Num Base
Push "${Num}"
Push "${Base}"
Call DecToBX
Pop "${Res}"
!macroend

!define DecToBX "!insertmacro DecToBX"


Di seguito il codice per fare l'operazione inversa, ovvero convertire un numero da qualsiasi base numerica in decimale:


Function BXToDec
Exch $R2 ; base
Exch
Exch $R1 ; number
Push $R0 ; result
Exch 2
Push $R3
StrCpy $R0 0

Loop:
StrCpy $R3 $R1 1 0
${IndexOf} $R3 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" $R3
System::Int64Op $R0 * $R2
Pop $R0 ; vale -1 in caso di errore
System::Int64Op $R0 + $R3
Pop $R0
StrCpy $R1 $R1 "" 1
StrCmp $R1 "" 0 Loop

Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd

!macro BXToDec Res Num Base
Push "${Num}"
Push "${Base}"
Call BXToDec
Pop "${Res}"
!macroend

!define BXToDec "!insertmacro BXToDec"


La funzione BXToDec fa uso della macro IndexOf il cui codice si puo' recuperare dal seguente link: IndexOf source code

Esempio di utilizzo:

${DecToBX} $R0 0xF58DE 36 ; return LK2M
DetailPrint "result: $R0"

${BXToDec} $R0 "LK2M" 36 ; return 1005790 (0xF58DE)
DetailPrint "result: $R0"


Incrociano le due funzioni e' possibile fare una conversione da qualsiasi base numerica, ad esempio da base 16 a base 36:

${BXToDec} $R0 "F58DE" 16 ; return 1005790
${DecToBX} $R0 $R0 36 ; return LK2M
DetailPrint "result: $R0"


Entrambe le funzione non fanno alcun controllo sui parametri, ad esempio che la base sia nel range compreso tra 2 e 36.

Per verificare il risultato potete usare questo link: http://www.translatorscafe.com/cafe/units-converter/numbers/calculator/decimal-to-base-36