## Appending binary in QB

If you have questions about any aspect of QBasic programming, or would like to help fellow programmers solve their problems, check out this board!

Moderators: Pete, Mods

klaatu
Newbie
Posts: 2
Joined: Tue Mar 28, 2006 8:51 pm
Location: Palmcoast,Fl

### Appending binary in QB

Howdy!

How does one append 16 bit binary words together to form a double word?

I would like to offer the TEA program for encrypting files for Qb users but the lack of binary bit manipulation in Qb is killing me.

Any ideas?

yeah yeah...

K

RyanKelly
Coder
Posts: 48
Joined: Sun Jan 22, 2006 6:40 pm
Contact:
I assume you are working with little endian words and dwords.

Here LowWord and HighWord are variables of the type integer.

Code: Select all

``````dim dwordResult as Long
dim tL as Long
dim tH as Long

tL=LowWord
tH=Highword
dwordResult= (tH * 2^16) OR tL
``````
The problem here is dealing with the sign bit.
This can be dealt with, but it's never straight forward, and the best approach will vary depending on your situation. Here is one approach.

Code: Select all

``````FUNCTION MakeDword& (Lword AS INTEGER, Hword AS INTEGER)
DIM Lbyte1, Lbyte2, Hbyte1, Hbyte2 AS INTEGER
DIM result AS LONG
DIM rptr AS INTEGER
DEF SEG = VARSEG(Lword)
Lbyte1 = PEEK(VARPTR(Lword))
Hbyte1 = PEEK(VARPTR(Lword) + 1)
DEF SEG = VARSEG(Hword)
Lbyte2 = PEEK(VARPTR(Hword))
Hbyte2 = PEEK(VARPTR(Hword) + 1)
rptr = VARPTR(result)
DEF SEG = VARSEG(result)
POKE rptr, Lbyte1
POKE rptr + 1, Hbyte1
POKE rptr + 1, Lbyte2
POKE rptr + 1, Hbyte2
DEF SEG
MakeDword&= result
END FUNCTION
``````
You could simplify this with using a UDT.

Edit: Also, if you merely need to convert a very small number of variables, you could write the 16 bit words to a file in the proper order, then read them back as 32 bit dwords.
A riskier approach might involve manipulating array descriptors.
Last edited by RyanKelly on Wed Mar 29, 2006 7:25 pm, edited 1 time in total.

Zim
Veteran
Posts: 98
Joined: Mon Dec 05, 2005 4:31 pm
Location: Wisconsin, USA
Contact:

### combining bits

I had always wondered how to do (something like) this in QB 3 because QB 3 doesn't even have long integers! (shoot). Now maybe this won't work in QB 4 because of having to declare your sub's ahead of time, but I had always wondered about the concept of calling a sub and matching the parameter lists in the call and the sub. I was thinking they just need to have the same number of bytes regardless of what the manual says about matching the parameters and types.

I thought, what if you call a sub with 2 2-byte integers and recieve it (in the sub's parameter list) as 1 4-byte real? (In QB 4 you could use 2-byte short integers and 4-byte long integers.) So, I tried it, finally:

Code: Select all

``````defint i-n

i=23456
j=12345

call mix(i,j,d)
print i,j,d

call split(d,i,j)
print d,i,j

END

sub mix(x,y) static
'x is the 4-byte real input, y is the 4-byte real output
y=x
end sub

sub split(iin,jin,iout,jout) static
'all 4 variables are 2-byte integers
iout=iin: jout=jin
end sub
``````
and low and behold, it works! QB 3 simply lines up the actual bytes between the call and the sub. It doesn't care that the NUMBER of parameters isn't the same, just the number of bytes. So I can use the absence of checking actual paramter types to COMBINE or SPLIT two 2-byte integers and one 4-byte real and let QB do the math

I wonder if this works in QB 4 or FreeBasic?????
--- Zim ---
--- Time flies like an arrow, but fruit flies like a banana ---

RyanKelly
Coder
Posts: 48
Joined: Sun Jan 22, 2006 6:40 pm
Contact:

### Re: combining bits

Zim wrote: I wonder if this works in QB 4 or FreeBasic?????
Nope. QB 4.5 has stronger type checking. However, you might be able to use an assembly routine in a library that treats its parameters differently than the declaration you use.

Antoni
Veteran
Posts: 132
Joined: Wed Jun 15, 2005 3:01 pm
Contact:
For qbasic:

Code: Select all

``````'set 31 bits
dblword&=(loword% and &hffff&) or ((hiword% and &h7fff&)*&h10000&)
'set the sign bit if needed
if hiword% and &h8000 then dblword&= dblword& or &h80000000
``````
Another way (slower but cleaner)

Code: Select all

``````dblword&=cvl(mki\$(loword%)+mki\$(hiword%))
``````
In freebasic, just use an UNION
EDITED:

Code: Select all

``````type twoshorts
l as ushort
h as ushort
end type

union ilong
d as uinteger
i as twoshorts
end union

dim d as ilong

d.i.l=&h8000
d.i.h=&h8001

print hex(d.d)
sleep
``````
Last edited by Antoni on Sat Apr 01, 2006 5:30 am, edited 2 times in total.

RyanKelly
Coder
Posts: 48
Joined: Sun Jan 22, 2006 6:40 pm
Contact:
Antoni wrote:For qbasic:

Code: Select all

``````'set 31 bits
dblword&=(loword% and &hffff&) or ((hiword% and &h7fff&)*&h10000&)
'set the sign bit if needed
if hiword% and &h8000 then dblword&= dblword& or &h80000000
``````
All the time I've spent dealing with that sign bit and it never occurred to me to just mask it out to avoid the over flow error. If it was a snake it would have bitten me! Thank you.