Golden Blonde 发表于 2019-7-30 04:17:57

【VB6】坑爹的64位整数运算和16进制转换(半成品)

废话不说,直接上码。部分64位整数转换为【16进制字符串】的时候存在溢出问题,单纯的计算没问题。
Option Explicit

Private Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (ByVal dst As Long, ByVal src As Long, ByVal cBytes As Long)

Private Function i64toa(ByVal v As Currency) As String
        Dim hv As Long, lv As Long, i As Long
        Dim ls As String
        If v = 0 Then
                i64toa = "0": Exit Function
        Else
                v = v / 10000
        End If
        memcpy VarPtr(hv), VarPtr(v) + 4, 4
        memcpy VarPtr(lv), VarPtr(v) + 0, 4
        ls = Hex$(lv)
        i64toa = Hex$(hv) & String(8 - Len(ls), "0") & ls
        For i = 1 To Len(i64toa)
                If Left$(i64toa, 1) = "0" Then
                        i64toa = Mid$(i64toa, 2)
                Else
                        Exit For
                End If
        Next
End Function

Private Function atoi64(ByVal vs As String) As Currency
        atoi64 = CCur(CDec("&H" & vs))
End Function

Private Sub Command1_Click() '输出64位整数的【十六进制格式字符串】
        On Error Resume Next
        MsgBox i64toa(CCur(CDec("&H7FFFFFFFFFFF"))), , "极大值(64位系统用户模式最高地址)"
        MsgBox i64toa(CCur(CDec("&HFFFF000000000000"))), , "极小值(64位系统内核模式最低地址)"
        MsgBox i64toa(CCur(CDec("&H7FFFFFFFFFFFFFFF"))), , "最大值(溢出)"
        MsgBox i64toa(CCur(CDec("&H8000000000000000"))), , "最小值(溢出)"
End Sub

Private Sub Command2_Click() '【十六进制格式字符串】输出为64位整数
        On Error Resume Next
        MsgBox atoi64("7FFFFFFFFFFF"), , "极大值(64位系统用户模式最高地址)"
        MsgBox atoi64("FFFF000000000000"), , "极小值(64位系统内核模式最低地址)"
        MsgBox atoi64("7FFFFFFFFFFFFFFF"), , "最大值(溢出)"
        MsgBox atoi64("8000000000000000"), , "最小值(溢出)"
End Sub

Private Sub Command3_Click() '【十六进制字符串形式】的64位大整数的加减运算
        Dim a As String: a = "FFFFF80000000000"
        Dim b As String: b = "987654321"
        Dim c As String: c = "7FFF12345678"
        Dim d As String: d = "912345678"
        Dim e As String: e = "FFFFF80012345678"
        Dim f As String: f = "12345678"
        Dim g As String: g = "10000"
        Dim h As String: h = "ABCD"
        MsgBox i64toa(atoi64(a) + atoi64(b))
        MsgBox i64toa(atoi64(c) - atoi64(d))
        MsgBox i64toa(atoi64(e) - atoi64(f))
        MsgBox i64toa(atoi64(g) + atoi64(h))
        MsgBox i64toa(atoi64(g) - atoi64(h))
End Sub

0xAA55 发表于 2019-7-30 18:36:35

精华在于CDec、CCur这两个函数的利用

Ayala 发表于 2019-7-30 21:21:20

坑爹的溢出问题,我的话肯定会用Large_integer

Private Declare Sub memcpy Lib "kernel32" Alias "RtlMoveMemory" (ByVal dst As Long, ByVal src As Long, ByVal cBytes As Long)

Private Type mDec
lo As Long
hi As Long
hh As Long
End Type

Private Type mVar
ty As Integer
tyl As Integer
tt As Long
lo As Long
hi As Long
End Type

Private Function mmi64toa(ByVal sv As Variant) As String
Dim v As Variant: v = sv
Dim ss As String: ss = ""

Dim vDec As mDec
Dim vVar As mVar

memcpy VarPtr(vVar.ty), VarPtr(v), 16
memcpy VarPtr(vDec.lo), VarPtr(vVar.lo), 8
vDec.hh = vVar.tt

If vVar.tyl = &H8000 Then ss = "负数"

mmi64toa = ss & " " & Hex(vDec.hh) & "" & Hex(vDec.hi) & "" & Hex(vDec.lo)
End Function


Private Sub Form_Load()
Dim a As String: a = "79228162514264337593543950335"
Dim b As String: b = "-39614081257132168796771975167"
Dim c As String: c = "9223372036854775807"
Dim d As String: d = "&h1FFFFFFFF"
Dim e As String: e = "1"
Dim f As String: f = "-1"
Dim ss As String

ss = a & " : " & mmi64toa(CDec(a)) & vbCrLf & _
b & " : " & mmi64toa(CDec(b)) & vbCrLf & _
c & " : " & mmi64toa(CDec(c)) & vbCrLf & _
d & " : " & mmi64toa(CDec(d)) & vbCrLf & _
e & " : " & mmi64toa(CDec(e)) & vbCrLf & _
f & " : " & mmi64toa(CDec(f)) & vbCrLf
MsgBox ss
End Sub

乘简 发表于 2019-8-1 15:00:42

哇,这个代码对齐格式,记事本中浏览效果很好啊。。。
页: [1]
查看完整版本: 【VB6】坑爹的64位整数运算和16进制转换(半成品)