Convert numerals

  • Thread starter Thread starter Luciano
  • Start date Start date
L

Luciano

Hi,
Does somebody have any idea about how to develop some VBA function or macroaiming conversion of several numerals types and that could be used for small and large numbers(e.g. 100000000000 in decimal)? The major numerals basefor which I need this conversions are:
Binary (Base 2)
Ternary (Base 3)
Quaternary (Base 4)
Quinary (Baase 5)
Senary (Base 6)
Septenary (Base 7)
Octal (Base 8)
Nonary (Base 9)
Decimal (Base 10)
Undecimal (Base 11)
Duodecimal (Base 12)
Base 13
Hexadecimal (Base 16)
Vigesimal (Base 20)
and others...

Thanks in advance,
Luciano
 
Luciano said:
Does somebody have any idea about how to develop some VBA function or
macro aiming conversion of several numerals types and that could be used
for small and large numbers(e.g. 100000000000 in decimal)? The major
numerals base for which I need this conversions are:
Binary (Base 2)
Ternary (Base 3)
Quaternary (Base 4)
Quinary (Baase 5)
Senary (Base 6)
Septenary (Base 7)
Octal (Base 8)
Nonary (Base 9)
Decimal (Base 10)
Undecimal (Base 11)
Duodecimal (Base 12)
Base 13
Hexadecimal (Base 16)
Vigesimal (Base 20)
and others...

Homework, anyone?

Function toBase(ByVal what As Variant, base As Long) As String
'Should be able to handle any decimal number to the limits of a variant,
'and bases from 2 to 36.
If (base < 2) Or (base > 36) Or (Int(what) <> what) Then Exit Function
Dim tmp As String
Static digits As Variant
If IsEmpty(digits) Then digits = Array("0", "1", "2", "3", "4", "5", _
"6", "7", "8", "9", "A", "B", _
"C", "D", "E", "F", "G", "H", _
"I", "J", "K", "L", "M", "N", _
"O", "P", "Q", "R", "S", "T", _
"U", "V", "W", "X", "Y", "Z")
While (what <> 0)
tmp = digits(what Mod base) & tmp
what = what \ base
Wend
toBase = tmp
End Function

For base 37+ add your extra digits to the end of the array and change 36 to
your new max.
 
Em sexta-feira, 8 de março de 2013 22h22min07s UTC-3, Luciano escreveu:
Hi,

Does somebody have any idea about how to develop some VBA function or macro aiming conversion of several numerals types and that could be used for small and large numbers(e.g. 100000000000 in decimal)? The major numerals base for which I need this conversions are:

Binary (Base 2)

Ternary (Base 3)

Quaternary (Base 4)

Quinary (Baase 5)

Senary (Base 6)

Septenary (Base 7)

Octal (Base 8)

Nonary (Base 9)

Decimal (Base 10)

Undecimal (Base 11)

Duodecimal (Base 12)

Base 13

Hexadecimal (Base 16)

Vigesimal (Base 20)

and others...



Thanks in advance,

Luciano

Hi Auric,
Thank you very much!
However, do you have any idea about how coud I convert to any base instead only decimal to any other (e.g. binary to decimal or octal to binary, etc)?
Thanks in advance,
Luciano
 
Luciano said:
Em sexta-feira, 8 de março de 2013 22h22min07s UTC-3, Luciano escreveu:

Hi Auric,
Thank you very much!
However, do you have any idea about how coud I convert to any base instead only decimal to any other (e.g. binary to decimal or octal to binary, etc)?
Thanks in advance,
Luciano


do it twice.
from one base to decimal and decimal to the other base.
You just need another set of functions which convert any base to decimal.
 
thank Auric! for this very useful function
ps /
to prevent overtaking 2147483647, i added this line
If what > 2147483647 Then toBase = 0: Exit Function
but if you have another solution, i'm interested

isabelle

Le 2013-03-09 02:02, Auric__ a écrit :
 
isabelle said:
thank Auric! for this very useful function
Np.

ps /
to prevent overtaking 2147483647, i added this line
If what > 2147483647 Then toBase = 0: Exit Function
but if you have another solution, i'm interested

Damn, look at that, overflow. I didn't test very thoroughly, I guess. The
whole reason I made "what" a Variant was so you could pass large values; it
never occurred to me to actually *try* it. Sigh.

Here's a version with "what" as a Long. Instead of getting an overflow
*inside* my function, passing large values will overflow at the calling
line instead.

Function toBase(ByVal what As Long, base As Long) As String
'Should be able to handle any whole number to the limits of a Long,
'and bases from 2 to 36.
If (base < 2) Or (base > 36) Then Exit Function
Dim tmp As String, sign As Boolean
Static digits As Variant
If IsEmpty(digits) Then digits = Array("0", "1", "2", "3", "4", "5", _
"6", "7", "8", "9", "A", "B", _
"C", "D", "E", "F", "G", "H", _
"I", "J", "K", "L", "M", "N", _
"O", "P", "Q", "R", "S", "T", _
"U", "V", "W", "X", "Y", "Z")
sign = (what < 0)
what = Abs(what)
While (what <> 0)
tmp = digits(what Mod base) & tmp
what = what \ base
Wend
If sign Then tmp = "-" & tmp
toBase = tmp
End Function

....and by request from the OP, here's the reciprocal function. Note that if
you pass any characters that aren't in "digits" I give you error 13 ("Type
Mismatch").

Function fromBaseToDec(ByVal what As String, base As Long) As Variant
'Should be able to handle any whole number to the limits of a Variant,
'and bases from 2 to 36.
If (base < 2) Or (base > 36) Then Exit Function
Dim tmp As Variant, L0 As Long, sign As Boolean, digits As String
Dim chk As Long
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
sign = ("-" = Left$(what, 1))
If sign Then what = Mid$(what, 2)
what = UCase$(what)
For L0 = 1 To Len(what)
chk = InStr(digits, Mid$(what, L0, 1))
If chk < 1 Then Error 13: Exit Function
tmp = tmp + ((chk - 1) * (base ^ (Len(what) - L0)))
Next
If sign Then tmp = 0 - tmp
fromBaseToDec = tmp
End Function

This one I *did* test with large numbers. This:

fromBaseToDec("111111111111111", 11)

....returns 417724816941565, well beyond the limits of a Long.
 
Em sexta-feira, 8 de março de 2013 22h22min07s UTC-3, Luciano escreveu:
Hi,

Does somebody have any idea about how to develop some VBA function or macro aiming conversion of several numerals types and that could be used for small and large numbers(e.g. 100000000000 in decimal)? The major numerals base for which I need this conversions are:

Binary (Base 2)

Ternary (Base 3)

Quaternary (Base 4)

Quinary (Baase 5)

Senary (Base 6)

Septenary (Base 7)

Octal (Base 8)

Nonary (Base 9)

Decimal (Base 10)

Undecimal (Base 11)

Duodecimal (Base 12)

Base 13

Hexadecimal (Base 16)

Vigesimal (Base 20)

and others...



Thanks in advance,

Luciano

Fantastic Auric!!!! Thank you very much!
 
Em sexta-feira, 8 de março de 2013 22h22min07s UTC-3, Luciano escreveu:
Hi,

Does somebody have any idea about how to develop some VBA function or macro aiming conversion of several numerals types and that could be used for small and large numbers(e.g. 100000000000 in decimal)? The major numerals base for which I need this conversions are:

Binary (Base 2)

Ternary (Base 3)

Quaternary (Base 4)

Quinary (Baase 5)

Senary (Base 6)

Septenary (Base 7)

Octal (Base 8)

Nonary (Base 9)

Decimal (Base 10)

Undecimal (Base 11)

Duodecimal (Base 12)

Base 13

Hexadecimal (Base 16)

Vigesimal (Base 20)

and others...



Thanks in advance,

Luciano

I have tested for several number sizes and bases but the unique problem is that in spite of a base like 2 has only two notations (0,1) the function calculate a "possible" corresponding decimal if we type something that is notinside theses possible notations (e.g. if we type 22 in binary to decimal it calculates the number 6).
 
Luciano said:
I have tested for several number sizes and bases but the unique problem
is that in spite of a base like 2 has only two notations (0,1) the
function calculate a "possible" corresponding decimal if we type
something that is not inside theses possible notations (e.g. if we type
22 in binary to decimal it calculates the number 6).

(For others reading, he's referring to my fromBaseToDec function.)

You could make sure your inputs have the correct numerals in them before
passing them to my function.

Or, you can add this line right below the "Error 13" line:

If chk > base Then Error 9: Exit Function

Error 9 is "Subscript out of range".
 
Auric__ said:
Damn, look at that, overflow. I didn't test very thoroughly, I guess. The
whole reason I made "what" a Variant was so you could pass large values; it
never occurred to me to actually *try* it. Sigh.

Here's a version with "what" as a Long. Instead of getting an overflow
*inside* my function, passing large values will overflow at the calling
line instead.

Function toBase(ByVal what As Long, base As Long) As String
'Should be able to handle any whole number to the limits of a Long,
'and bases from 2 to 36.
If (base < 2) Or (base > 36) Then Exit Function
Dim tmp As String, sign As Boolean
Static digits As Variant
If IsEmpty(digits) Then digits = Array("0", "1", "2", "3", "4", "5", _
"6", "7", "8", "9", "A", "B", _
"C", "D", "E", "F", "G", "H", _
"I", "J", "K", "L", "M", "N", _
"O", "P", "Q", "R", "S", "T", _
"U", "V", "W", "X", "Y", "Z")
sign = (what < 0)
what = Abs(what)
While (what <> 0)
tmp = digits(what Mod base) & tmp
what = what \ base
Wend
If sign Then tmp = "-" & tmp
toBase = tmp
End Function

...and by request from the OP, here's the reciprocal function. Note that if
you pass any characters that aren't in "digits" I give you error 13 ("Type
Mismatch").

Function fromBaseToDec(ByVal what As String, base As Long) As Variant
'Should be able to handle any whole number to the limits of a Variant,
'and bases from 2 to 36.
If (base < 2) Or (base > 36) Then Exit Function
Dim tmp As Variant, L0 As Long, sign As Boolean, digits As String
Dim chk As Long
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
sign = ("-" = Left$(what, 1))
If sign Then what = Mid$(what, 2)
what = UCase$(what)
For L0 = 1 To Len(what)
chk = InStr(digits, Mid$(what, L0, 1))
If chk < 1 Then Error 13: Exit Function
tmp = tmp + ((chk - 1) * (base ^ (Len(what) - L0)))
Next
If sign Then tmp = 0 - tmp
fromBaseToDec = tmp
End Function

This one I *did* test with large numbers. This:

fromBaseToDec("111111111111111", 11)

...returns 417724816941565, well beyond the limits of a Long.


return result as a string.
 
Back
Top