输入0到32,代表IP4网络掩码中的一位数(对应于/ 19中的CIDR块大小,是什么,]
Prototype:
Function NetMaskFromBitCount(BitCount As Long) As Long
'Logic here '
End Function
注意,由于VB6不会做无符号运算,因此这很复杂,因此常规的数学技巧常常不起作用。如果(Number And &H80000000)
不为零,则Number \ 2
将与SHR操作不同。
我想出了几种方法,但是我不认为它们很优雅,而且可能还不那么快。
我的一个想法是策略性地使用CopyMemory API,这非常快。我过去已经解决了一些有符号/无符号的Long问题,只需将Long写入一个字节(0到3)并根据需要处理每个部分。
由于我还使用inet_ntoa()和inet_addr()Windows API函数,并且它们以相反的字节顺序返回IP序列号,所以以相反的顺序返回字节的解决方案很棒(我已经有一个函数如果需要的话,翻转字节顺序,但是避免它也会很好)。
示例:
Input = 2
Output = -1073741824 (&HC0000000)
Alternate Output = 12 (&HC0, reverse byte order)
Input = 19
Output = -8192 (&HFFFFE000)
Alternate Output = 14745599 (&H00E0FFFF, reverse byte order)
工作解决方案很好,但是我要寻找优雅或快速。
Function NetMaskFromBitCount(ByVal lBitCount As Long) As Long
If lBitCount > 0 Then
NetMaskFromBitCount = -1 * 2 ^ (32 - lBitCount)
End If
End Function
必须将此参数设置为ByVal
!
测试在这里进行:
Debug.Assert NetMaskFromBitCount(19) = &HFFFFE000
Debug.Assert NetMaskFromBitCount(2) = &HC0000000
Debug.Assert NetMaskFromBitCount(32) = &HFFFFFFFF
Debug.Assert NetMaskFromBitCount(0) = 0
您只有32个可能的输入,因此我想最快的解决方案是引用数组中所有32个输出的lookup table。它不会赢得优雅的积分。警告:air code
Function DoIt(ByVal Input As Long) As Long
Static lArray() As Long
Static bInitialised As Boolean
If Not bInitialised Then
ReDim Preserve lArray(0 To 31)
lArray(0) = 0
lArray(1) = &H80000000
lArray(2) = &HC0000000
' etc... '
bInitialised = True
End If
DoIt = lArray(Input) ' for bonus marks raises an error on illegal input '
End Function
[如果您需要更一般的内容,VBSpeed会长期竞争fast VB6 left-shifts。
ShiftLeft04
,使用了一些可怕的技巧,抱歉,我的意思是聪明才智,使VB6中获得内联汇编器。你会笑,你会哭,你会在恐怖中尖叫...ShiftLeft04
大约是200线全纯VB6。花费1.3倍的时间,但仍然很快。 我没有VB6,但是这是我在.Net中的处理方法
ShiftLeft06