Link to home
Start Free TrialLog in
Avatar of matlurz
matlurz

asked on

Strings in VB?

I'm still having trouble understanding strings in VB 5.0.  I think that I'm too used to processing strings as character arrays as in C/C++.  Anyhow recently I asked the question "How do I convert a string of Integers to its' binary equivalent"  Someone answered with a function that looked like this...

Public Function Long2Binary(ByVal lValue&) As String

     Dim sBinary$
     Dim iBit%
     Dim lBitValue&

   sBinary = ""
   For iBit = 0 to 14
     lBitValue = 2 ^ iBit
     sBinary = IIF((lValue And iBitValue, "1", "0")&sBinary
   Next
Long2Binary = sBinary
End Function

Well, I got the function to work by converting the string into a long & then passing that value into the function, but I still don't understand how the function manipulates each value...if you can explain and offer a suggestion as to how to reverse the process of this function...that it to convert a binary into an integer, it's worth another 300 pts.
Avatar of cymbolic
cymbolic

We really have to be careful here.  One must keep in mind the external reperesentation of these numbers as well.  I am referring to the MS representation of numbers using the LoHi arrangement of values, such as you might see in a file dump of a n integer or long value.  The above function works on an actual long integer numeric value, but if you were to read 4 bytes of a long integer value from a file, it wouldn't work.  More to follow.  
How it works is pretty simple.  It is using iBit and lBitValue to count from 1 to 14 in powers of two.

For iBit = 0 to 14

simply counts from 0 to 14

iBitValue = 2^iBit

is stating that iBitValue should be 2 to the power of iBit.

sBinary = IIF(lValue And iBitValue, "1","0") & sBinary

This is using the logical 'And' operator to compare lValue and iBitValue.  If the value returns true, it sets sBinary to 1 and appends the original sBinary string to the end.  If it returns false, it sets sBinary to 0 and appends the original string to the end of it.

Long2Binary = sBinary

simply returns the string that was produced by the above loop.

As for the reverse of this process, I don't have any idea.  That's why I'm submitting this as a comment instead of answer.  Hope this helps a little, though.
How it works is pretty simple.  It is using iBit and lBitValue to count from 1 to 14 in powers of two.

For iBit = 0 to 14

simply counts from 0 to 14

iBitValue = 2^iBit

is stating that iBitValue should be 2 to the power of iBit.

sBinary = IIF(lValue And iBitValue, "1","0") & sBinary

This is using the logical 'And' operator to compare lValue and iBitValue.  If the value returns true, it sets sBinary to 1 and appends the original sBinary string to the end.  If it returns false, it sets sBinary to 0 and appends the original string to the end of it.

Long2Binary = sBinary

simply returns the string that was produced by the above loop.

As for the reverse of this process, I don't have any idea.  That's why I'm submitting this as a comment instead of answer.  Hope this helps a little, though.
Avatar of matlurz

ASKER

Still don't get it!  During the comparison, is the entire value of the lValue being evaluated each time through the loop?  I just don't get it ...HELP!
So, if in the above value you want to see the bit representation of the long integer, then you would have to wind up with 32 bits, not 16.  So, to be commensurate with the above function you would input an integer (2 bytes, 16 bits) rather than a long (4 bytes, 32 bits).  

The other complication is that negative numbers are stored in a 1's compliment form, and this will impact your calculations as well, and the code to provide that bit configuration is not in the above algorithm.

Basically, (is this a pun for VB), the above algorithm works by setting a bit in the output binary value based upon a power of 2 value in the numeric input, which is the intrinsic method of representing numbers.  You or the bit position representing the power of two, and the bit is turned in the result byte string.

However, file methods store numbers in a strangely reversed order, an integer of 16 bits, rather than being stored consecutively is devided in to byte componenets, and they are store in reversed order (instead of HI,LO, its LO,HI).  So here is
a function using basic that will convert a 4 byte string from a file opened as binary and read as a string, that was originally saved as an integer.  This code recognizes the reversed byte storage sequence:

FUNCTION stolong& (s$)
'dim yer hexers here
hex2& = ASC(MID$(s$, 2, 1))
hex2& = hex2& * 256
hex3& = ASC(MID$(s$, 4, 1))
hex3& = hex3& * 4096
hex4& = ASC(MID$(s$, 3, 1))
hex4& = hex4& * 65536
stolong& = (ASC(MID$(s$, 1, 1))) + hex2& + hex3& + hex4&

Of course, if you actual have numeric strings, that is a string like:
"123456" then its a no brainer, you use CLNG() or CINT() to convert the numeric string value to a long or integer, as long as it's in range.

Now, if you were to write that long number using binary output
i.e., open f$ for binary as #1
       put #1,,Lng&  <write the long value number

it would be stored such that use could use the listed functio above to read it like:
       open f$ for binary as #1
       x$=space$(4)  'sets input buffer length
       get #1,,x$
       lng&=stolong&(x$)

then you have your long value back.  Older Quick basic had a more direct recognition of handling numbers as strings, it had a MKL$ function that would take an integer and create it's string representation, so you could work with strings of numbers, whether integers or longs, as string data, for binary reading and writing.  Somewhare along the way that went by the wayside, probably because of the unicode representation of strings in Windows, where each character is actually 2 bytes, rather than one.

 
Avatar of matlurz

ASKER

Whoa! That was heavy?&#(@)!  I should have mentioned though that I this program simply reads a string from a textbox, converts that value, & outputs the changed value.  I want it to work with integers, binary, octal, & hex values and to do implicit conversion with any of these types.(i.e int to hex, hex to octal, oct to binary etc,..etc,..etc,..) But thanks for the insight....m
Regarding internal storage of strings:

Basic actual stores a string descriptor, which has a lentght and pointer to the actual string.  So if you pass a string variable to a function, basic passes a pointer to the pointer, which is OK as long as you are in basic.  That's why you see a ByValue modifier when setting up calling declaratives to external functions.  You have to force Basic to pass the actual string, instead of an address of a string descriptor

Hope this helps!
ASKER CERTIFIED SOLUTION
Avatar of mrmick
mrmick

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
By the way, the BinaryStr function will accept a boolean, byte, integer or long, and will even convert a number in a string variable and return a string first.  It returns a string containing the appropriate number of bits 1, 8, 16, or 32 depending on the data type passed.

The BinToLong function goes the other way, however, It returns a decimal number as a Long Integer.  You can convert the returned long using to other types:

i = cint(RetLong) 'Converts return value to integer data type
b = cbyte(RetLong) 'Converts return value to byte data type
etc...