How to use VBScript on a 32-bit operating system to display 64-bit double numbers?

I have a device that contains a 64-digit (double) parameter. I can use the Modbus protocol to read its Double parameter in two parts. So I use a bitwise operation to divide the 64-digit number into Two 32-digit numbers.

Example: 2289225.841082 (decimal) = 41417724-EBA8953E (hexadecimal)

You can check and test the Hex dialog at the following site : Http://babbage.cs.qc.edu/IEEE-754/ Copy 41417724EBA8953E and paste the “value to be analyzed” edit box in the above site, and then press Enter.

But in the transmission two After a 32-bit integer, I cannot merge it into the original 64-bit number. I tried to use the CDbl and FormatNumber functions in VBScript, but it failed!

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)

So, how to use VBScript to display 64-bit numbers on a 32-bit operating system?

Assuming pure VBScript, the “simple” answer to this is to write a bignum add and multiply and then use Calculate the answer this way.

Using the code in RosettaCode, I created the following VeryLargeInteger class and a Hex64 function, which indicates that 4702170486407730494 is the 64-bit decimal equivalent value 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)< br /> 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< br /> 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< br /> 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(S tr_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) sResult = "0" & ​​sResult
Wend
pad = sResult
End Function
End Class

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

Dim Sixteen(16)< br /> 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")< br /> 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< br />End Function

WScript.Echo Hex64("41417724EBA8953E")

I want to say “enjoy”, but it has been more than six months since the original post, so You are likely to find another solution. Nevertheless, this is very interesting.

Later

Another way to do Hex64, if you want to avoid pre-calculating the power of 16 is:

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

I have a device with 64-digit (double) parameters. I can use Modbus protocol in two parts Read its Double parameter. So I use bitwise operation to divide the 64-digit number into two 32-digit numbers.

Example: 2289225.841082 (decimal) = 41417724-EBA8953E (hexadecimal)< /p>

You can check and test the Hex dialog at the following site: http://babbage.cs.qc.edu/IEEE-754/ copy 41417724EBA8953E and paste the “value to analyze” edit box in the above site , And press Enter.

But after transferring two 32-bit integers, I cannot merge them into the original 64-bit number. I tried to use the CDbl and FormatNumber functions in VBScript, but it failed !

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)

So, how to use VBScript to display 64-bit numbers on a 32-bit operating system?

Assuming pure VBScript, the “simple” answer to this is to write a bignum add and multiply and then calculate the answer in this way.

Using the code in RosettaCode, I created the following VeryLargeInteger class and a Hex64 function, which indicates that 4702170486407730494 is the 64-bit decimal equivalent of 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)
sR esult = 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< br />'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) 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")< br /> 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))< br /> 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")

I want to say “enjoy”, but it’s been more than six months since the original post, so you are likely to find another solution. Still, it’s fun.

Later

Another way to do Hex64, if you want to avoid pre-calculating the power of 16 is:

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 St ep -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

< p>

Leave a Comment

Your email address will not be published.