Jim Mack
10/17/2011 11:11:00 AM
> Thanks.
>
> Decided to take a little from each.
> Using a Hex$ of the count right now starting at 1 (all non-zero entries).
> This compresses the digits somewhat.
>
> So how about a F.a.s.t Radix Alphabet Function to compress even more?
>
> so something like the following...
> please review and comment. mistakes? make it faster please?
> Thanks!
> I guess all the printable characters is the limit.
> This one goes 0..9A..Z for now.
> Fun!
This is going to fail one of your initial criteria -- it's going to be
slow. It's too general-purpose and needlessly complex for the
conditions you specified.
You said that the number of keys would be fairly small, so you could
restrict this to a single base (say 94) with a limit of MAXLONG or
less. The technique is simply repeated division by 94 and add 33 to
each result, and deal with the remainder. The value then contains only
printable characters (33..126) and is 9x compacted.
You could cut the amount of code by 2/3, stick to integer math and
avoid string concats. Also, if the idea is just to generate keys, you
don't need the reverse operation at all, right?
Really, for a small key range where speed is an issue, CStr(key) would
be fast and reasonably compact.
--
Jim
> '
> ' mdlRadix
> '
> Option Explicit
>
> ' ===========================================
> Public Const cRadixBin As Integer = 2
> Public Const cRadixOct As Integer = 8
> Public Const cRadixDec As Integer = 10
> Public Const cRadixHex As Integer = 16
> Public Const cRadixAbet As Integer = 36
> ' ===========================================
>
> Private m_avPow() As Variant
>
> Public Function RadixToDec(sNum As String, xRad As Integer) As Variant
>
> Dim lIx As Long
> Dim dRes As Variant
> Dim sVal As String
> Dim dVal As Variant
> Dim lLength As Long
>
> dRes = CDec(dRes)
> dVal = CDec(dVal)
>
> lLength = Len(sNum)
> sNum = UCase$(sNum)
>
> For lIx = 1 To lLength
> sVal = Asc(Mid$(sNum, lLength - lIx + 1, 1))
> Select Case sVal
> Case vbKey0 To vbKey9
> dVal = sVal - vbKey0
>
> Case vbKeyA To vbKeyZ
> dVal = sVal - 55
>
> Case Else
> ' error
> End Select
> dRes = dRes + pow(xRad, (lIx - 1)) * dVal
> Next lIx
>
> RadixToDec = dRes
>
> End Function 'RadixToDec
>
> Private Function pow(ByVal lBase As Long, ByVal lExp As Long) As Variant
>
> ' calculate powers of numbers.
>
> Dim lIdx As Long
>
> pow = CDec(lBase)
> If lExp = 0 Then
> pow = 1
> Else
> For lIdx = 1 To lExp - 1
> pow = pow * lBase
> Next
> End If
>
> End Function 'Pow
>
> Public Function DecToRadix(ByVal vDec As Variant, ByVal iRadix As
> Integer, Optional bSuffix As Boolean = False, Optional bDecCommas As
> Boolean = False) As String
>
> On Error GoTo DecToRadixErr
>
> Dim dLen As Double
> Dim sResult As String
> Dim sDigit As String
> Dim vVal As Variant
> Dim vNorm As Variant
> Dim iX As Integer
>
> vVal = CDec(0)
> vNorm = CDec(0)
>
> If vDec = 0 Then
> DecToRadix = "0"
> Else
> dLen = (Log(vDec) / Log(iRadix)) + 1
> If dLen <> Int(dLen) Then dLen = Int(dLen) + 1
>
> For iX = 0 To dLen - 1
> vNorm = (iRadix ^ (dLen - iX - 1))
> vVal = Fix(Val(vDec) / (vNorm))
>
> Select Case vVal
> Case 10 To 35
> sDigit = Chr$(65 + Val(vVal) - 10)
>
> Case Else
> sDigit = Int(Val(vDec) / iRadix ^ (dLen - iX - 1))
>
> End Select
> sResult = sResult & sDigit
> vVal = (iRadix) ^ (dLen - iX - 1)
> vDec = vDec - (Int(Val(vDec) / vVal) * vVal)
> Next iX
> Do
> If Left$(sResult, 1) = "0" Then
> sResult = Mid$(sResult, 2)
> Else
> Exit Do
> End If
> Loop
> If (iRadix = cRadixDec) And bDecCommas Then
> DecToRadix = FormatNbr(Val(sResult))
> Else
> DecToRadix = sResult
> End If
> End If
> If bSuffix Then
> Select Case iRadix
> Case cRadixBin
> DecToRadix = DecToRadix & " (B)"
> Case cRadixOct
> DecToRadix = DecToRadix & " (O)"
> Case cRadixDec
> DecToRadix = DecToRadix & " (D)"
> Case cRadixHex
> DecToRadix = DecToRadix & " (H)"
> Case cRadixAbet
> DecToRadix = DecToRadix & " (A)"
> Case Else
> DecToRadix = DecToRadix & " (" & CStr(iRadix) & ")"
> End Select
> End If
>
> DecToRadixExit:
> Exit Function
>
> DecToRadixErr:
> 'Resume
> DecToRadix = "#ERROR#"
> Resume DecToRadixExit
>
> End Function 'DecToRadix
--
Jim