2012-12-08 64 views
5

我有一個包含64位數(雙)參數的設備。我可以使用Modbus協議分兩部分閱讀其雙參數。所以我使用按位操作將64位數字分成兩個32位數字。如何在32位操作系統上使用VBScript顯示64位雙數?

例子:2289225.841082(十進制)= 41417724-EBA8953E(十六進制)

您可以檢查,並在以下網站測試六角談話:在上述網站,然後按http://babbage.cs.qc.edu/IEEE-754/複製41417724EBA8953E和粘貼「價值分析」編輯框輸入。

但是在傳送完兩個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

假設純粹的VBScript,「簡單」的答案是編寫一個bignum add和multiply,然後以這種方式計算答案。

RosettaCode使用代碼,我創建了以下VeryLargeInteger類和Hex64函數說4702170486407730494是0x41417724EBA8953E

的64位十進制等效
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("ABCDEF",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("ABCDEF",theDigit)-1 
     theAnswer = VLI.ADD(theAnswer,VLI.MULTIPLY(thePower,theMultiplier)) 
     thePower = VLI.MULTIPLY(thePower,"16") 
    Next 
    Hex64b = theAnswer 
End Function 
相關問題