整数布尔/位数组没有循环
我有一个数字(比如5),我首先想将它转换为二进制(101),然后在VBA中分成{1,0,1}
或布尔值{True,False,True}
有没有办法做到这一点没有循环?
我可以转换为二进制没有循环在我的代码与工作表公式如下
myBinaryNum = [DEC2BIN(myDecInteger,[places])]
但是我被告知工作表函数效率很低,而且这个function是非常有限的。
我不知道如何拆分成一个数组,而不需要用MID
循环数字。 有什么像strConv
数字?
您可以先使用WorksheetFunction.Dec2Bin
将该值转换为“01”string。 然后用代码0
或1
replace每个“0”,“1”,并将结果转换为Byte
数组:
Public Function ToBitArray(ByVal value As Long) As Byte() Dim str As String str = WorksheetFunction.Dec2Bin(value) ' "101" str = Replace(Replace(str, "0", ChrW(0)), "1", ChrW(1)) ' "\u0001\u0000\u0001" ToBitArray = StrConv(str, vbFromUnicode) ' [1, 0, 1] End Function
但Dec2Bin
限于511,使用string是相当昂贵的。 所以如果你的目标是要获得最好的性能,那么你应该使用一个循环来读取每一个位:
Public Function ToBitArray(ByVal value As Long) As Byte() Dim arr(0 To 31) As Byte, i As Long i = 32& Do While value i = i - 1 arr(i) = value And 1 value = value \ 2 Loop ToBitArray = MidB(arr, i + 1) ' trim leading zeros End Function
我在这里发现了另一个问题的这个整洁的代码。 基本上,你可以确定你的string是ASCII,因为它是1和0。
你所做的是你使用
Dim my_string As String my_string = CStr("your binary number")
把你的二进制数转换成一个string
接着
Dim buff() As String buff = Split(StrConv(my_string, vbUnicode), Chr$(0)) ReDim Preserve buff(UBound(buff) - 1
把这个string分割成一个数组,其中buff是你的数组
我想你可能已经从上面的其他答案得到了你需要的所有东西,但是如果你想要一个简单的函数来取得小数并返回数组。
Function dec_to_binary_array(decNum As Integer) Dim arr() As String, NumAsString As String NumAsString = Application.Dec2Bin(decNum) arr = Split(StrConv(NumAsString, vbUnicode), vbNullChar) ReDim Preserve arr(UBound(arr) - 1) dec_to_binary_array = arr End Function
调用Application.Dec2Bin(n)
不是非常昂贵,只会花费一个延迟的调用。 使用下面的函数将任何整数转换成一个位数组:
Function Bits(n as long) Dim s As String: s = Application.Dec2Bin(n) Dim ar: ar = Split(StrConv(s, vbUnicode), vbNullChar) Bits = ar End Function
ps: s
将只包含0
和1
,这是ASCII字符,所以拆分技术是完全有效的。
如果这是你所需要的,请检查这个代码:你可以用任何单元格的值引用代替数字5,这只是例子:
Sub dectobinary() Dim BinaryString As String BinaryString = "5" tempval = Dec2Bin(BinaryString) MsgBox tempval End Sub Function Dec2Bin(ByVal DecimalIn As Variant) As String Dec2Bin = "" DecimalIn = Int(CDec(DecimalIn)) Do While DecimalIn <> 0 Dec2BinTemp = Format$(DecimalIn - 2 * Int(DecimalIn / 2)) If Dec2BinTemp = "1" Then Dec2Bin = "True" & "," & Dec2Bin Else Dec2Bin = "False" & "," & Dec2Bin End If DecimalIn = Int(DecimalIn / 2) Loop End Function
只需将lngNumber值更改为所需的数字
Public Sub sChangeNumberToBinaryArray() Dim strBinaryNumber As String Dim strBinaryArray() As String Dim lngNumber As Long lngNumber = 5 strBinaryNumber = DecToBin(lngNumber) strBinaryArray() = Split(strBinaryNumber, "|") End Sub
函数DecToBin(ByVal varDecimalIn As Variant)作为string
Dim lngCounter As Long DecToBin = "" varDecimalIn = Int(CDec(varDecimalIn)) lngCounter = 1 Do While varDecimalIn <> 0 If lngCounter = 1 Then DecToBin = Format$(varDecimalIn - 2 * Int(varDecimalIn / 2)) & DecToBin lngCounter = lngCounter + 1 Else DecToBin = Format$(varDecimalIn - 2 * Int(varDecimalIn / 2)) & "|" & DecToBin lngCounter = lngCounter + 1 End If varDecimalIn = Int(varDecimalIn / 2) Loop End Function