如何在32位操作系统上使用VBScript显示64位双号?

时间:2012-12-08 15:22:38

标签: vbscript double

我的设备包含64位数(双)参数。我可以使用Modbus协议分两部分读取其Double参数。所以我使用按位运算将64位数分成两个32位数。

示例:2289225.841082(十进制)= 41417724-EBA8953E(十六进制)

您可以在以下网站中检查并测试Hex对话:http://babbage.cs.qc.edu/IEEE-754/复制41417724EBA8953E并粘贴上面站点中的“要分析的值”编辑框,然后按Enter键。

但是在传输了两个32位整数后,我可以将它合并到原始的64位数。我尝试在VBScript中使用CDblFormatNumber函数,但它失败了!

Dim nL, nH, fL, fH, f64 
nL = 1094809380 ' 4141 7724
nH = 3953694014 ' EBA8 953E
fL = CDbl($nL)
fH = CDbl($nH)
f64 = CDbl((fH * CDbl(2 ^ 32)) + CDbl(fL))
$strNum64 = FormatNumber( f64, 2)  

那么,如何在32位操作系统上使用VBScript显示64位数?

1 个答案:

答案 0 :(得分:1)

假设纯粹的VBScript,对此的“简单”答案是写一个bignum add and multiply然后以这种方式计算答案。

使用RosettaCode中的代码,我创建了以下VeryLargeInteger类和一个Hex64函数,该函数表明4702170486407730494是64位十进制等效值0x41417724EBA8953E

Option Explicit
Class VeryLongInteger
    'http://rosettacode.org/wiki/Long_Multiplication#Liberty_BASIC
    Public Function MULTIPLY(Str_A, Str_B)
        Dim signA, signB, sResult, Str_Shift, i, d, Str_T
        signA = 1
        If Left(Str_A,1) = "-" Then 
            Str_A = Mid(Str_A,2)
            signA = -1
        End If
        signB = 1
        If Left(Str_B,1) = "-" Then 
            Str_B = Mid(Str_B,2)
            signB = -1
        End If
        sResult = vbNullString
        Str_T = vbNullString
        Str_shift = vbNullString
        For i = Len(Str_A) To 1 Step -1
            d = CInt(Mid(Str_A,i,1))
            Str_T = MULTBYDIGIT(Str_B, d)
            sResult = ADD(sResult, Str_T & Str_shift)
            Str_shift = Str_shift & "0"
            'print d, Str_T, sResult 
        Next
        If signA * signB < 0 Then sResult = "-" + sResult
        'print sResult
        MULTIPLY = sResult
    End Function

    Private Function MULTBYDIGIT(Str_A, d)
        Dim sResult, carry, i, a, c
        'multiply Str_A by digit d
        sResult = vbNullString
        carry = 0
        For i = Len(Str_A) To 1 Step -1
            a = CInt(Mid(Str_A,i,1))
            c = a * d + carry
            carry = c \ 10
            c = c Mod 10
            'print a, c
            sResult = CStr(c) & sResult 
        Next
        If carry > 0 Then sResult = CStr(carry) & sResult
        'print sResult
        MULTBYDIGIT = sResult
    End Function

    Public Function ADD(Str_A, Str_B)
        Dim L, sResult, carry, i, a, b, c
        'add Str_A + Str_B, for now only positive
        l = MAX(Len(Str_A), Len(Str_B))
        Str_A=PAD(Str_A,l)
        Str_B=PAD(Str_B,l)
        sResult = vbNullString 'result
        carry = 0
        For i = l To 1 Step -1
            a = CInt(Mid(Str_A,i,1))
            b = CInt(Mid(Str_B,i,1))
            c = a + b + carry
            carry = Int(c/10)
            c = c Mod 10
            'print a, b, c
            sResult = CStr(c) & sResult
        Next
        If carry>0 Then sResult = CStr(carry) & sResult
        'print sResult
        ADD = sResult
    End Function

    Private Function Max(a,b)
        If a > b Then
            Max = a
        Else
            Max = b
        End If
    End Function

    Private Function pad(a,n)  'pad from right with 0 to length n
        Dim sResult
        sResult = a
        While Len(sResult) < n
            sResult = "0" & sResult
        Wend
        pad = sResult
    End Function
End Class

Function Hex64(sHex)
    Dim VLI
    Set VLI = New VeryLongInteger

    Dim Sixteen(16)
    Sixteen(0) = "1"
    Sixteen(1) = "16"
    Sixteen(2) = VLI.MULTIPLY(Sixteen(1),"16")
    Sixteen(3) = VLI.MULTIPLY(Sixteen(2),"16")
    Sixteen(4) = VLI.MULTIPLY(Sixteen(3),"16")
    Sixteen(5) = VLI.MULTIPLY(Sixteen(4),"16")
    Sixteen(6) = VLI.MULTIPLY(Sixteen(5),"16")
    Sixteen(7) = VLI.MULTIPLY(Sixteen(6),"16")
    Sixteen(8) = VLI.MULTIPLY(Sixteen(7),"16")
    Sixteen(9) = VLI.MULTIPLY(Sixteen(8),"16")
    Sixteen(10) = VLI.MULTIPLY(Sixteen(9),"16")
    Sixteen(11) = VLI.MULTIPLY(Sixteen(10),"16")
    Sixteen(12) = VLI.MULTIPLY(Sixteen(11),"16")
    Sixteen(13) = VLI.MULTIPLY(Sixteen(12),"16")
    Sixteen(14) = VLI.MULTIPLY(Sixteen(13),"16")
    Sixteen(15) = VLI.MULTIPLY(Sixteen(14),"16")

    Dim theAnswer, i, theDigit, theMultiplier, thePower, aPower
    theAnswer = "0"
    aPower = 0
    For i = Len(sHex) To 1 Step -1
        theDigit = UCase(Mid(sHex,i,1))
        theMultiplier = InStr("0123456789ABCDEF",theDigit)-1
        thePower = Sixteen(aPower)
        thePower = VLI.MULTIPLY(CStr(theMultiplier),thePower)
        theAnswer = VLI.ADD(theAnswer,thePower )
        aPower = aPower + 1
    Next
    Hex64 = theAnswer
End Function

WScript.Echo Hex64("41417724EBA8953E")

我想说“享受”,但距离最初的帖子已有六个多月了,所以你很可能找到另一个解决方案。尽管如此,这很有趣。

<强> LATER

另一种做Hex64的方法,如果你想避免预先计算16的权力是:

Function Hex64b(sHex)
    Dim VLI
    Set VLI = New VeryLongInteger       
    Dim theAnswer, i, theDigit, theMultiplier, thePower, aPower
    theAnswer = "0"
    thePower = "1"
    For i = Len(sHex) To 1 Step -1
        theDigit = UCase(Mid(sHex,i,1))
        theMultiplier = InStr("0123456789ABCDEF",theDigit)-1
        theAnswer = VLI.ADD(theAnswer,VLI.MULTIPLY(thePower,theMultiplier))
        thePower = VLI.MULTIPLY(thePower,"16")
    Next
    Hex64b = theAnswer
End Function