gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 21:46:23 24 4
gpt4 key购买 nike

我有一个包含 64 位数字(双)参数的设备。我可以使用 Modbus 协议(protocol)分两部分读取它的 Double 参数。所以我使用按位运算将 64 位数字拆分为两个 32 位数字。

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

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

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

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 位数字?

最佳答案

假设纯 VBScript,对此的“简单”答案是编写一个 bignum 加法和乘法,然后以这种方式计算答案。

使用来自 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("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")

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

稍后

如果您想避免预先计算 16 的幂,则执行 Hex64 的另一种方法是:
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

关于vbscript - 如何在 32 位操作系统上使用 VBScript 显示 64 位双数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13778856/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com