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

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

Appending binary in QB

Post by klaatu »

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...
Klaatu barada niktow t'yall

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

Post by RyanKelly »

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.
User avatar
Zim
Veteran
Posts: 98
Joined: Mon Dec 05, 2005 4:31 pm
Location: Wisconsin, USA
Contact:

combining bits

Post by Zim »

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

Post by RyanKelly »

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.

In FB parameter type checking is used to facilitate function overloading.
Antoni
Veteran
Posts: 132
Joined: Wed Jun 15, 2005 3:01 pm
Contact:

Post by Antoni »

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:

Post by RyanKelly »

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.
Post Reply