Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Binary to Decimal

Status
Not open for further replies.

moonbase

Programmer
Nov 18, 2002
57
GB
I need to convert a binary number, read from a text file, to it's decimal equivalent. It's in two's complement format, i.e can be negative.
Does anybody have a suitable routine or can anyone point me in the right direction?

Many thanks
 
If its not homework, its a fairly trivial problem. What have you got so far?

___________________________________________________________
If you want the best response to a question, please check out FAQ222-2244 first.
'If we're supposed to work in Hex, why have we only got A fingers?'
Drive a Steam Roller
Steam Engine Prints
 
The file was generated by a cobol program on a mainframe and I need to access the data. It may be straightforward, I just didn't want to reinvent the wheel.
 
Just loop through the string character by character from right to left multiplying by increasing powers of 2, using the last (rightmost) character for sign

___________________________________________________________
If you want the best response to a question, please check out FAQ222-2244 first.
'If we're supposed to work in Hex, why have we only got A fingers?'
Drive a Steam Roller
Steam Engine Prints
 
Assuming you are refering to "Three-bit two's-complement " there will
only be 8 possible conversions so if your data is already parsed
you could pass the data to a function like this:

Code:
Public Function Binary2Deci(3DigiBinary As String) As Long
    Select Case valtoconv
        Case "000"
            Bin2Comp_Conv = 0
        Case "001"
            Bin2Comp_Conv = 1
        Case "010"
            Bin2Comp_Conv = 2
        Case "011"
            Bin2Comp_Conv = 3
        Case "100"
            Bin2Comp_Conv = -4
        Case "101"
            Bin2Comp_Conv = -3
        Case "110"
            Bin2Comp_Conv = -2
        Case "111"
            Bin2Comp_Conv = -1
    End Select
End Function
[THUMBSUP]
 
Oops I changed the function name in above code here is working example:


Public Function Binary2Deci(3DigiBinary As String) As Long
Select Case 3DigiBinary
Case "000"
Binary2Deci = 0
Case "001"
Binary2Deci = 1
Case "010"
Binary2Deci = 2
Case "011"
Binary2Deci = 3
Case "100"
Binary2Deci = -4
Case "101"
Binary2Deci = -3
Case "110"
Binary2Deci = -2
Case "111"
Binary2Deci = -1
End Select
End Function
 
>Assuming you are refering to "Three-bit two's-complement "

Why on earth would you make that assumption?
 
Just re-read my post - obviously <last (rightmost)> should read <last (leftmost)> as you are reading right to left.

___________________________________________________________
If you want the best response to a question, please check out FAQ222-2244 first.
'If we're supposed to work in Hex, why have we only got A fingers?'
Drive a Steam Roller
Steam Engine Prints
 
>Why on earth would you make that assumption?

Because the solution would be the easiest.

Heres a solution for 3bit 4bit and 8bit:

Place a TextBox and a Command Button on a form and paste:

Code:
Private Sub Command1_Click()
    MsgBox TwosCompConvert(Text1.Text, FourBit)
End Sub

Private Sub Form_Load()
    Text1.Text = 1000
End Sub

And in a Module Paste
Code:
Public Enum EnumBits
    ThreeBit = 0
    FourBit = 1
    EightBit = 2
End Enum

Public Function TwosCompConvert(BinaryString As String, E_Bits As EnumBits) As Long
    Dim LargestVal As Long
    Dim TempLong As Long
    
    'Determine Largest and Smallest values
    Select Case E_Bits
        Case ThreeBit
            LargestVal = 3
        Case FourBit
            LargestVal = 7
        Case EightBit
            LargestVal = 127
    End Select
    
    'Test
    TempLong = BinToDec(BinaryString)
    If TempLong > LargestVal Then
        'Produce Negative Result
        TwosCompConvert = BinToNegDec(TempLong, BinaryString)
    Else
        'Result is Positive
        TwosCompConvert = TempLong
    End If
    
    
End Function

Function BinToDec(value As String) As Long
    'Function by Francesco Balena
    Dim result As Long, i As Integer, exponent As Integer
    
    For i = Len(value) To 1 Step -1
        Select Case Asc(Mid$(value, i, 1))
            Case 48      ' "0", do nothing
            Case 49      ' "1", add the corresponding power of 2
                result = result Or Power2(exponent)
            Case Else
                Err.Raise 5      ' Invalid procedure call or argument
        End Select
        exponent = exponent + 1
    Next
    BinToDec = result
End Function

Function BinToNegDec(NumToSubtractFrom As Long, value As String) As Long
    'Function inspired by Francesco Balena
'Loop from left to right subtracting from NumToSubtractFrom as you go
    Dim result As Long
    Dim i As Integer
    Dim exponent As Integer
    
    exponent = Len(value)
    
    For i = 1 To Len(value)
        Select Case Asc(Mid$(value, i, 1))
            Case 48      ' "0", do nothing
            Case 49      ' "1", add the corresponding power of 2
                NumToSubtractFrom = NumToSubtractFrom Or NumToSubtractFrom - Power2(exponent)
            Case Else
                Err.Raise 5      ' Invalid procedure call or argument
        End Select
        exponent = exponent - 1
    Next
    BinToNegDec = NumToSubtractFrom
End Function

Function Power2(ByVal exponent As Long) As Long
    'Function by Francesco Balena
Static res(0 To 31) As Long
    Dim i As Long
    
    ' rule out errors
    If exponent < 0 Or exponent > 31 Then Err.Raise 5
    
    ' initialize the array at the first call
    If res(0) = 0 Then
        res(0) = 1
        For i = 1 To 30
            res(i) = res(i - 1) * 2
        Next
        ' this is a special case
        res(31) = &H80000000
    End If
    
    ' return the result
    Power2 = res(exponent)
        
End Function
 
Hi. It may (or may not) be trivial but it's not that easy.
The original number is for example 00 00 00 00 20 5F in hex.
 
> Hi. It may (or may not) be trivial but it's not that easy
Yep, actually my last posted solution is broken, shouldnt post on no sleep.
 
Using John's method (only as left to right), this should do it:
Code:
Sub negbin2dec()
Dim BinString As String, temp As String
Dim DecimalNum As Long, i As Integer, j As Integer
binaer = Selection.Text
dezi = 0
j = 2
For i = Len(BinString) - 1 To 1 Step -1
    DecimalNum = DecimalNum + (Mid(BinString, j, 1) * (2 ^ i))
    j = j + 1
Next i

If Left(BinString, 1) = 1 Then
    temp = "-" & CStr(DecimalNum)
    DecimalNum = CLng(temp)
End If
End Sub

[b][navy]"We had to turn off that service to comply with the CDA Bill."[/navy]
- The Bastard Operator From Hell[/b]
 
Using John's method (only as left to right), this should do it:
Code:
Sub negbin2dec()
Dim BinString As String, temp As String
Dim DecimalNum As Long, i As Integer, j As Integer
binaer = Selection.Text
dezi = 0
j = 2
For i = Len(BinString) - 1 To 1 Step -1
    DecimalNum = DecimalNum + (Mid(BinString, j, 1) * (2 ^ i))
    j = j + 1
Next i

If Left(BinString, 1) = 1 Then
    temp = "-" & CStr(DecimalNum)
    DecimalNum = CLng(temp)
End If
End Sub

[navy]"We had to turn off that service to comply with the CDA Bill."[/navy]
- The Bastard Operator From Hell
 
Sorry if the title of the thread is misleading. I haven't got a string of 0's and 1's. It's just binary/hex in the file, e.g. 00 00 00 00 20 5F in hex. So the first thing to do is unpack it.
 
The title is misleading?

You mean you have neither a binary number nor a text file but rather "text" which you wish to read from a binary file?

That's about as much alike as an elephant is to goldfish!

Now please do tell, what exactly do you wish to read in what way and convert it into what?

[navy]"We had to turn off that service to comply with the CDA Bill."[/navy]
- The Bastard Operator From Hell
 
In the text file there are a series of characters representing a binary number in two's complement format. Conventionally they are represented in hex format: 00 00 00 00 20 5F
 
Converting hex to binary is simple enough.
you just cycle through the string, converting each hex digit into binary:
Code:
Private Function Hex2Bin(hx As String) As String
  Select Case hx
    Case "0": Hex2Bin = "0000": Case "1": Hex2Bin = "0001"
    Case "2": Hex2Bin = "0010": Case "3": Hex2Bin = "0011"
    Case "4": Hex2Bin = "0100": Case "5": Hex2Bin = "0101"
    Case "6": Hex2Bin = "0110": Case "7": Hex2Bin = "0111"
    Case "8": Hex2Bin = "1000": Case "9": Hex2Bin = "1001"
    Case "A": Hex2Bin = "1010": Case "B": Hex2Bin = "1011"
    Case "C": Hex2Bin = "1100": Case "D": Hex2Bin = "1101"
    Case "E": Hex2Bin = "1110": Case "F": Hex2Bin = "1111"
  End Select
End Function

If you want to re-convert to decimal value with regard to this binary number being with a negative flag bit then just add my previous code...

[navy]"We had to turn off that service to comply with the CDA Bill."[/navy]
- The Bastard Operator From Hell
 
Thanks for your help but I don't think you've quite got it.
The rightmost byte in my example is hex 5F, this represents 0101 1111 binary, 95 decimal. So to use your code I first need to extract each nibble. Also negative numbers in two's complement format are not just postive numbers with the first bit set to 1.
 
Your data appears to be HEX not binary. Just take your data 2 characters at a time and use the built in translation by sticking &H in front and taking the Val
Code:
Dim temp As Long
temp = Val("&H" & myinputpair)
If temp > 127 Then temp = temp - 256
myoutputint = temp

___________________________________________________________
If you want the best response to a question, please check out FAQ222-2244 first.
'If we're supposed to work in Hex, why have we only got A fingers?'
Drive a Steam Roller
Steam Engine Prints
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top