2017-07-24 11 views
5

Tôi có một số (ví dụ 5) mà tôi sẽ lần đầu tiên muốn chuyển đổi sang nhị phân (101) và sau đó tách ra thành một mảng bit {1,0,1} hoặc Booleans {True,False,True} trong VBAInteger để boolean/mảng bit mà không lặp

Liệu có cách nào để làm điều này mà không lặp?

tôi có thể chuyển đổi sang nhị phân mà không lặp trong mã của tôi với công thức bảng tính như sau

myBinaryNum = [DEC2BIN(myDecInteger,[places])] 

Nhưng tôi đã nói rằng chức năng bảng tính rất hiệu quả, và điều này là đặc biệt hạn chế.

Tôi không chắc chắn cách tách thành mảng mà không lặp qua các chữ số với MID. Có điều gì giống như strConv cho các số không?

Trả lời

4

Trước tiên, bạn có thể chuyển đổi các giá trị cho một " 01 "chuỗi với WorksheetFunction.Dec2Bin. Sau đó thay thế từng "0", "1" với mã 0 hoặc 1 và đúc kết quả vào một mảng 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 

Nhưng Dec2Bin được giới hạn trong 511 và làm việc với chuỗi là khá tốn kém. Vì vậy, nếu mục tiêu của bạn là để có được hiệu suất tốt nhất, sau đó bạn nên sử dụng một vòng lặp để đọc mỗi bit:

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 
+0

, trong dung dịch thứ hai của bạn (với một vòng lặp), ý nghĩa của 'i = 32 ** & **' là gì, không phải '&' khai báo giá trị trước đó là kiểu 'Long', nhưng vì' i' đã được khai báo và 32 chỉ là một số , Tôi không thực sự chắc chắn điều đó có nghĩa là gì? – Greedo

+1

'32 &' có nghĩa là 32 được sử dụng như một 'Long'. Chỉ một mình '32' được sử dụng như một' Số nguyên'. Nó rất hữu ích khi giá trị được gán cho một biến thể và khi bạn cần nó để giữ một 'Long' hoặc để tránh một tràn trên một hoạt động. Nó không quan trọng ở đây vì nó được tự động chuyển thành kiểu 'i' là' Long'. –

1

Tôi tìm thấy mã gọn gàng này trên một câu hỏi khác here tại SO. Về cơ bản, bạn có thể chắc chắn chuỗi của bạn là ASCII do thực tế nó là 1 và 0.

Những gì bạn làm là bạn sử dụng

Dim my_string As String 

my_string = CStr("your binary number") 

Để bật số nhị phân của bạn thành một chuỗi

Và sau đó

Dim buff() As String 
buff = Split(StrConv(my_string, vbUnicode), Chr$(0)) 
ReDim Preserve buff(UBound(buff) - 1 

Để chia chuỗi thành một mảng nơi da bò là mảng của bạn

0

Gọi Application.Dec2Bin(n) không phải là thực sự đắt tiền, nó onl y chi phí một cuộc gọi bị ràng buộc trễ. Sử dụng chức năng dưới đây để chuyển đổi bất kỳ số nguyên vào một mảng bit:

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 

P.S .: s sẽ chỉ chứa 01 đó là các ký tự ASCII, vì vậy các kỹ thuật phân chia là hoàn toàn hợp lệ.

-1

Vui lòng kiểm tra mã này nếu đây là những gì bạn cần: Bạn có thể thay thế các chữ số 5 bởi bất kỳ tài liệu tham khảo giá trị tế bào, điều này chỉ là và Ví dụ:

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 
+1

giải pháp này có một vòng lặp – jsotola

-1

Chỉ cần thay đổi giá trị lngNumber đến số mong muốn của bạn

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 

Chức năng DecToBin (ByVal varDecimalIn As Variant) As 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 
+0

giải pháp này có một Novice câu hỏi lặp – jsotola

1

Tôi nghĩ rằng bạn đã có thể có mọi thứ bạn cần trên từ câu trả lời khác, nhưng nếu bạn muốn có một chức năng đơn giản mà mất số thập phân và trả về mảng ..

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 
Các vấn đề liên quan