是否有任何方法可以在VisualBasic6.0中生成从0到&HFFFFFFFF的随机数?
我使用以下函数
Function RandomNumberLong(Lowerbound As Long, Upperbound As Long) As Long
RandomNumberLong = Clng((Upperbound - Lowerbound + 1) * Rnd + Lowerbound)
End Function
如果我用
x = RandomNumberLong(0,&HFFFFFFFF)
它总是返回0。
这里的问题是long可以容纳的最大值是7 7FFFFFFF或小数为2147483647,那么我应该如何修复这个问题呢?即使我使用单个数据类型,它也总是返回负数而不带符号数字。
按MSDN长型
长(长整数)变量存储为有符号32位(4字节)数字,其值从-2,147,483,648到2,147,483,647不等。长时间的类型声明字符是符号(&)。
但是FFFFFFFF的值等于溢出的-1或4294967294。
我想我对此感到困惑。
编辑:
由于这似乎有点复杂,我编写了一个小Shell代码来使用RDTSC指令来生成一个随机长数,包括签名和无符号。
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long
Option Explicit
Private Sub Form_Load()
Dim x(1 To 10) As Byte, VAL As Long
CopyMemory x(1), &H60, 1 'PUSHAD
CopyMemory x(2), &H310F, 2 'RDTSC EAX holds a random value
CopyMemory x(4), &HA3, 1 'MOV EAX
CopyMemory x(5), VarPtr(VAL), 4 'Pointer of variable // MOV DWORD [VAL],EAX
CopyMemory x(9), &H61, 1 'POPAD
CopyMemory x(10), &HC3, 1 'RET
CallWindowProc VarPtr(x(1)), 0, 0, 0, 0 'Call the shellcode
MsgBox VAL
End Sub
发布于 2013-05-01 19:47:47
&HFFFFFFFF
-表示32位有符号整数,而&HFFFFFFFF
的值溢出该整数并成为-1
,因此,当您调用RandomNumberLong
函数时,将0传递给低绑定,-1传递给上限。
为了在Vb.NET中解决这个问题,请使用&HFFFFFFFFL
或&HFFFFFFFF&
来指示长类型文字。我不知道如何在VB6中和上面示例中的VB.NET中一样快速地修复这个问题。我想您需要编写自己的函数来将大的HEX数字转换为双倍,并传递数字而不是HEX。
编辑:我认为VB6不允许您将&HFFFFFFFF
转换为除基数16以外的任何东西,这会导致-1:
编辑2:通过将&
添加到末尾,可以将一些十六进制数字转换为其他数据类型:
&HFFFF = -1
&HFFFF& = 65535
尽管如此,VB6中的十六进制数似乎还是有限制的(只有16?)因为:
VB.NET:
&HFFFFFFFF&=4294967295
VB6:
&HFFFFFFFF&=-1
编译器通常将整数文字解析为十进制(基数10)数字系统中的整数。您可以使用&H前缀强制整数文字为十六进制(基数16),也可以强制它为带有&O前缀的八进制(基8)。前缀后面的数字必须适合数字系统。
发布于 2013-05-01 22:48:19
事实上,VB6 Long
是32位有符号整数数据类型.因此,它根本无法存储&HFFFFFFFF
(MSDN)。但是(1)无论如何,您似乎都可以使用Long
,(2)您不需要解释您的用例是什么,而且如果仅仅在一个积极的范围内工作真的那么关键的话。
可以使用以下函数从整个Long
数据类型(即从-&H80000000
到&H7FFFFFFF
)生成随机的Long
值:
Function RandomNumberLong() As Long
RandomNumberLong = &H7FFFFFFF * Rnd() + (-1 - &H7FFFFFFF) * Rnd()
End Function
发布于 2013-05-02 07:26:59
问题是,VB6将任何退出"F“到-1的十六进制数转换为-1。
这将使您的函数使用-1作为其上限,并使其返回0。
通过将8个数字分成2个变量和4个数字,您仍然有相同的问题,因为VB6仍然会将&HFFFF转换为-1,这将使您的函数再次返回0。
一种解决方案是在转换前将H 10000添加到4位变量中,并在转换完成后对Val(“&H 10000”)进行减法。
在此之后,您可以使用这两个值获得2个随机数,并将它们组合成1个随机8位十六进制数。
下面是一个测试项目,它展示了我的意思:
'1 form with:
' 1 command button: name=Command1
Option Explicit
Private Sub Command1_Click()
Dim strX As String
Dim lngX As Long
strX = RndHex("FFFFFFFF")
lngX = Val("&H" & strX)
Caption = strX & " = " & CStr(Hex$(lngX)) & " = " & CStr(lngX)
End Sub
Function RndHex(strMax As String) As String
Dim strMax1 As String, strMax2 As String
Dim lngMax1 As Long, lngMax2 As Long
Dim lngVal1 As Long, lngVal2 As Long
Dim strVal1 As String, strVal2 As String
'make sure max is 8 digits
strMax1 = Right$("00000000" & strMax, 8)
'split max in 2 parts
strMax2 = Right$(strMax1, 4)
strMax1 = Left$(strMax1, 4)
'convert max values from string to values
lngMax1 = Val("&H1" & strMax1) - Val("&H10000")
lngMax2 = Val("&H1" & strMax2) - Val("&H10000")
'calculate separate random values
lngVal1 = CLng(lngMax1 + 1) * Rnd
lngVal2 = CLng(lngMax2 + 1) * Rnd
'convert values to 4 digit hex strings
strVal1 = Right$("0000" & Hex$(lngVal1), 4)
strVal2 = Right$("0000" & Hex$(lngVal2), 4)
'combine 2 random values and return the result as an 8 digit hex string
RndHex = strVal1 & strVal2
End Function
Private Sub Form_Load()
'seed random generator with system timer
Randomize
End Sub
运行上面的项目并单击命令按钮并查看表单标题中的值。
https://stackoverflow.com/questions/16324104
复制相似问题