Converting VERY large number to a hex string

3k Views Asked by At
Public Function MyMod(a As Double, b As Double) As Double
MyMod = a - Int(a / b) * b
End Function

This code doesn't work as it doesn't correctly show the remainder do be able to then calculate HEX.

Correct : 10009335357561071 / 16 = 62558345984756.69 VB6 MyMod returns 0 instead of a valid remainder.

I have been unable to figure out how to convert such a large value into a hex string?

4

There are 4 best solutions below

4
On BEST ANSWER

I was able to code it myself. Because of the vb6 limitations of the size of a number, I had to go about it in different ways. I needed this to be able to covert VERY LARGE WHOLE numbers to Binary and Hexadecimal.

This this code, there are three functions you can use. 1) Decimal 2 Hex 2) Binary to Hex 3) Decimal 2 Binary

The code works and gives me CORRECT returns for the VERY large numbers.

Public Function Dec2Hex(Dec As String) As String
 Dec2Hex = Binary2Hex(Dec2Bin(Dec))
End Function

Public Function Binary2Hex(Binary As String, Optional Pos As Long = 0) As String
 Dim tic As Long
 Dim Sz As Long
 Dim x As Long
 Dim z As Long
 Dim AT As Long
 Dim Hx As Long
 Dim HxB As String
 Dim xstart As Long
 Dim xstop As Long

 HxB = vbNullString
 If InStrB(Binary, " ") <> 0 Then Binary = Replace(Binary, " ", "")
 Sz = Len(Binary)

 xstart = Sz
 xstop = xstart - 3

 Do
 AT = 0
 Hx = 0
 If xstop < 1 Then xstop = 1
 For x = xstart To xstop Step -1
   AT = AT + 1
   If AscB(Mid$(Binary, x, 1)) = 49 Then
     Select Case AT
        Case 1: Hx = Hx + 1
        Case 2: Hx = Hx + 2
        Case 3: Hx = Hx + 4
        Case 4: Hx = Hx + 8
     End Select
   End If
 Next x
 HxB = Digit2Hex(CStr(Hx)) + HxB
 If x <= 1 Then Exit Do
 xstart = x
 xstop = xstart - 3
 Loop
 Binary2Hex = HxB
End Function

Private Function Digit2Hex(digit As String) As String
 Select Case digit
   Case "0": Digit2Hex = "0"
   Case "1": Digit2Hex = "1"
   Case "2": Digit2Hex = "2"
   Case "3": Digit2Hex = "3"
   Case "4": Digit2Hex = "4"
   Case "5": Digit2Hex = "5"
   Case "6": Digit2Hex = "6"
   Case "7": Digit2Hex = "7"
   Case "8": Digit2Hex = "8"
   Case "9": Digit2Hex = "9"
   Case "10": Digit2Hex = "A"
   Case "11": Digit2Hex = "B"
   Case "12": Digit2Hex = "C"
   Case "13": Digit2Hex = "D"
   Case "14": Digit2Hex = "E"
   Case "15": Digit2Hex = "F"
   Case Else: Digit2Hex = vbNullString
 End Select
End Function

Public Function Dec2Bin(Dec As String) As String
 Dim Bin As String
 Dim Var As Variant
 Dim p As Long
 Dim Tmp As String

 Bin = vbNullString
 Tmp = Dec
 Do
  Bin = IIf(isEven(Tmp), "0", "1") + Bin
  Var = CDec(Tmp)
  Var = Var / 2
  Tmp = CStr(Var)
  p = InStr(Tmp, ".")
  If p > 0 Then Tmp = Mid(Tmp, 1, p - 1)
  If Len(Tmp) = 1 Then
   If CLng(Tmp) = 0 Then Exit Do
  End If
 Loop
 Dec2Bin = Bin
End Function

Public Function isEven(Dec As String) As Boolean
 Dim OE As Long
 Dim myDec As Variant

 OE = CLng(Right$(CStr(Dec), 1))
 isEven = (OE = 0 Or OE = 2 Or OE = 4 Or OE = 6 Or OE = 8)

End Function
1
On

Here is a working sample (using Fix), that is not mine, credit to http://visualbasic.ittoolbox.com/groups/technical-functional/visualbasic-l/vb60-hex-function-overflow-error-2744358.

Private Function MyHex(ByVal TempDec As Double) As String 
    Dim TNo As Integer 

    MyHex = "" 
    Do 
        TNo = TempDec - (Fix(TempDec / 16) * 16) 
        If TNo > 9 Then 
            MyHex = Chr(55 + TNo) & MyHex 
        Else 
            MyHex = TNo & MyHex 
        End If 
        TempDec = Fix(TempDec / 16) 
    Loop Until (TempDec = 0) 
End Function 
0
On

The only convenient data type in VB6 that can accurately represent 10009335357561071 is the Variant's Decimal subtype. Both Double and Currency native types lack the precision required.

There is also the matter of handling signed values and for that matter how many bytes of precision are desired, whether leading zeros should be suppressed, and probably others.

It is very hard to conceive of a need for this in a real application.

Even if we presume you are doing something "especially special" or if some instructor has given you this problem as an aid to general understanding...

... there just isn't much you can do with this without a BigNum library of some sort, or possibly using Decimal with some care though it only gains you a few more digits of precision.

0
On
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Function Dec2Hex(ByVal strDec As Variant) As String

Dim mybyte(0 To 19) As Byte
Dim lp As Long

CopyMemory mybyte(0), ByVal VarPtr(CDec(strDec)), 16

' Quick reorganise so we can then just step through the entire thing in one loop
For lp = 7 To 4 Step -1
    mybyte(12 + lp) = mybyte(lp)
Next

' Build the hex string
For lp = 19 To 8 Step -1
    If (Not Len(Dec2Hex) And mybyte(lp) <> 0) Or Len(Dec2Hex) Then
        'Dec2Hex = Dec2Hex & Format(hex(mybyte(lp)), IIf(Len(Dec2Hex), "00", "0"))
        Dec2Hex = Dec2Hex & IIf(Len(Dec2Hex), Right$("0" & hex(mybyte(lp)), 2), hex(mybyte(lp)))
    End If
Next

End Function