This course teaches how to install and configure Windows Server 2012 R2. It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

I've been trying to find a decimal to binary and binary to decimal function that works correctly with negative numbers, but so far, none have held up to the challenge. I want this to work in Visual Basic, but the VB code will eventually be ported to ASP, so I would rather avoid using external components.

For example, I am reading a Long value from a file. This value is negative, eg, -1487631. When I attempt to convert this to binary using the following function, I of course get a 0 since the function only does positive numbers.

If I try to read the Long as 4 bytes, then convert each byte into an 8 bit binary string, and concatate the 4 strings together, then try to convert the binary string back to a long, I get a number like 1487630.

My question is, how exactly are 4 byte negative longs (or 2 byte negative integers, etc) stored in either files or memory? What's the best way to correctly convert from a negative or positive number of an arbitrary byte length (anything from 1 byte to 32 bytes, even odd ones such as 5, 17, etc)?

Here are the functions I'm currently using.

Public Function Dec2Bin(ByVal Num As Variant) As String

Dim x As Integer

For x = 100 To 0 Step -1 ' I don't expect to ever use a number bigger than (2 ^ 100)

If Num >= (2 ^ x) Then

' Stop

Dec2Bin = Dec2Bin & "1"

Num = Num - (2 ^ x)

Else

Dec2Bin = Dec2Bin & "0"

End If

Next x

Do While Left(Dec2Bin, 1) = "0"

Dec2Bin = Mid(Dec2Bin, 2) ' Remove all extra 0's from the front.

Loop

Do Until Len(Dec2Bin) Mod 8 = 0 And Len(Dec2Bin) <> 0 ' Make sure there are 8 'bits' returned

Dec2Bin = "0" & Dec2Bin

Loop

End Function

Public Function Bin2Dec(ByVal Bin As String) As Variant

Dim x As Integer

For x = 1 To Len(Bin)

Bin2Dec = Bin2Dec + Int(Mid(StrReverse(Bin), x, 1) * (2 ^ (x - 1)))

Next x

End Function

Current points set at 250, but I'm willing to increase it for a prompt response, or information that goes above and beyond what I've asked for.

James

For example, I am reading a Long value from a file. This value is negative, eg, -1487631. When I attempt to convert this to binary using the following function, I of course get a 0 since the function only does positive numbers.

If I try to read the Long as 4 bytes, then convert each byte into an 8 bit binary string, and concatate the 4 strings together, then try to convert the binary string back to a long, I get a number like 1487630.

My question is, how exactly are 4 byte negative longs (or 2 byte negative integers, etc) stored in either files or memory? What's the best way to correctly convert from a negative or positive number of an arbitrary byte length (anything from 1 byte to 32 bytes, even odd ones such as 5, 17, etc)?

Here are the functions I'm currently using.

Public Function Dec2Bin(ByVal Num As Variant) As String

Dim x As Integer

For x = 100 To 0 Step -1 ' I don't expect to ever use a number bigger than (2 ^ 100)

If Num >= (2 ^ x) Then

' Stop

Dec2Bin = Dec2Bin & "1"

Num = Num - (2 ^ x)

Else

Dec2Bin = Dec2Bin & "0"

End If

Next x

Do While Left(Dec2Bin, 1) = "0"

Dec2Bin = Mid(Dec2Bin, 2) ' Remove all extra 0's from the front.

Loop

Do Until Len(Dec2Bin) Mod 8 = 0 And Len(Dec2Bin) <> 0 ' Make sure there are 8 'bits' returned

Dec2Bin = "0" & Dec2Bin

Loop

End Function

Public Function Bin2Dec(ByVal Bin As String) As Variant

Dim x As Integer

For x = 1 To Len(Bin)

Bin2Dec = Bin2Dec + Int(Mid(StrReverse(Bin), x, 1) * (2 ^ (x - 1)))

Next x

End Function

Current points set at 250, but I'm willing to increase it for a prompt response, or information that goes above and beyond what I've asked for.

James

Public Function Bin2Dec(Bin as string) as Long

Dim x as integer

for x = 1 to len(bin)

Bin2Dec = Bin2Dec OR Int(Mid(StrReverse(Bin), x, 1) * (2 ^ (x - 1)))

next

End Function

Public Function Dec2Bin(Dec as Long) as String

Dim x as integer

for x = 1 to 32

Dec2Bin = iif(mid(dec,x,1) = "1",1,0)*(2^(32-x))

next

End Function

That's all freehand, so there might be some glitches, but hopefully you get the idea.

Zaphod.

Zaphod.

Fewf, that turned out to be a lot harder than I thought it would be. Be aware that this uses the internal representation of longs to do its work, which is done in little endian, so some of the loops might seem backwards, but they aren't really. This will work with bytes, integers and longs normally for Bin2Dec, and will also work for Dec2Bin, but it will always return a 32 bit value, you can just truncate the first 2 or 3 bytes for integers and bytes respectively since they will all be either 1 or 0 anyway and are not needed.

Hope this does the trick.

Zaphod.

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Function Dec2Bin(ByVal Value As Long) As String

Dim strRetVal As String

Dim arrBytes(0 To 3) As Byte

Dim i As Integer

Dim j As Integer

CopyMemory arrBytes(0), Value, 4

For i = 3 To 0 Step -1

For j = 7 To 0 Step -1

strRetVal = strRetVal & (arrBytes(i) And (2 ^ j)) / (2 ^ j)

Next

Next

Dec2Bin = strRetVal

End Function

Private Function Bin2Dec(ByVal Value As String) As Long

Dim lngRetVal As Long

Dim arrBytes(0 To 3) As Byte

Dim strSign As String

Dim i As Integer

Dim j As Integer

Dim k As Integer

' Pad the string with the sign bit

Value = String(32 - Len(Value), Left(Value, 1)) & Value

k = 1

For i = 3 To 0 Step -1

For j = 7 To 0 Step -1

If Mid(Value, k, 1) = "1" Then

arrBytes(i) = arrBytes(i) Or (2 ^ (j))

End If

k = k + 1

Next

Next

CopyMemory lngRetVal, arrBytes(0), 4

Bin2Dec = lngRetVal

End Function

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.

Zaphod.

Private Function Dec2Bin(ByVal Value As Long) As String

Dim blnIsNegative As Boolean

Dim intPower As Integer

Dim strRetVal As String

blnIsNegative = (Value < 0)

Value = Abs(Value)

While Value > 0

strRetVal = CStr(Value Mod 2) & strRetVal

Value = Value \ 2

Wend

strRetVal = String(32 - Len(strRetVal), "0") & strRetVal

If blnIsNegative Then

strRetVal = TwosComplement(strRetVal)

End If

Dec2Bin = strRetVal

End Function

Private Function Bin2Dec(ByVal Value As String) As Long

Dim blnIsNegative As Boolean

Dim intPower As Integer

Dim lngRetVal As Long

blnIsNegative = (Left(Value, 1) = "1")

If blnIsNegative Then

Value = TwosComplement(Value)

End If

For intPower = 0 To Len(Value) - 1

If Mid(Value, Len(Value) - intPower, 1) = "1" Then

lngRetVal = lngRetVal + (2 ^ intPower)

End If

Next

If blnIsNegative Then

lngRetVal = -lngRetVal

End If

Bin2Dec = lngRetVal

End Function

Private Function TwosComplement(ByVal Value As String) As String

Dim intPos As Integer

Value = Replace(Value, "0", "x")

Value = Replace(Value, "1", "0")

Value = Replace(Value, "x", "1")

intPos = InStrRev(Value, "0")

Value = Left(Value, intPos - 1) & "1" & String(32 - intPos, "0")

TwosComplement = Value

End Function