Bit(lhs,Rhs)

General FreeBASIC programming questions.
Dinosaur
Posts: 1330
Joined: Jul 24, 2005 1:13
Location: Hervey Bay
Contact:

Bit(lhs,Rhs)

Hi all

In an effort to speed up a project where I have to read hundreds of input bits, and assign them to elements of a udt.I came up with.

Code: Select all

`Bz = Inp(Settings.PortAddr(Port))For Bits = 1 To 8   BitCount += 1   Settings.PortBit(BitCount) = Bit(Bz,Bits)Next`
To my disappointment (but documented) Bit returned "-1" if the bit is set. So I cant use it directly in my program logic, I have to convert it to "+1" if it is ON, and leave it at 0, if not.
Going with the theory that two negatives make a positive, i tried

Code: Select all

`Settings.PortBit(BitCount) = -Bit(Az,Bits)`
Note the minus before Bit. This worked, but my question:
Is this intended behaviour or a fluke.?

Regards
vdecampo
Posts: 2982
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:
Return Value:

Returns an Integer value of `-1` if the bit is set, or `0` if the bit is cleared.

If you want to test for a particular bit you could try...

Code: Select all

`Bz = Inp(Settings.PortAddr(Port))For Bits = 0 To 7        BitCount += 1        Settings.PortBit(BitCount) = Bz and (2^Bits)Next `

Of course you need to chage PortBit array bounds to 0-7.

-Vince
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA
It seems to me that you can use the same index for both, and ANDing with 1 will yield a return value of 0 or 1.

Code: Select all

`for i as integer = 0 to 7    Settings.PortBit(i) = Bit(Bz,i) and 1next`
Dinosaur
Posts: 1330
Joined: Jul 24, 2005 1:13
Location: Hervey Bay
Contact:
Hi all

vdecampo, your suggestion prints the value of the bit, and not 0 or 1.

It seems to me that you can use the same index for both,

That was so obvious, that I should have picked that up. (senior's moment)
What I didnt realise that " -1 And +1" gave the result of +1

Will test for speed difference now.
Does anyone know if the -Bit(lhs,rhs) was intended ?

Regards

Edit: Actually Michael, I was using the separate Bitcount to increment the udt element (from 1 to 384). I also had to break up the task of reading 48 x 8 bit ports, as it was taking 350 mSec to read all of them.
counting_pine
Posts: 6190
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs
BIT() is just a simple macro, designed to return a boolean result for whether the bit is set.
This allows an easy way to test for when a bit is unset by doing "if not bit(a, n) then ..."

You might be wondering why -1 is returned instead of 1, but it's because -1 is a standard BASIC value for True. It's the number you get if you set all the bits in a signed integer, while 0 is what you get if you clear all the bits, and you can easily flip between the two values using the NOT operation.
It just (quasi-)coincidentally happens that -TRUE is -(-1) is 1, which can be convenient sometimes.

BIT() might not be ideal for what you need, but if you want to, it's really easy and more efficient to define your own macro to do what you want, e.g.

Code: Select all

`#define bit1(a, n) ( ((a) shr (n)) and 1)for i as integer = 7 to 0 step -1    print bit1(91, i);nextprint`
Dinosaur
Posts: 1330
Joined: Jul 24, 2005 1:13
Location: Hervey Bay
Contact:
Hi all

counting_pine your suggestion works well, and I ended up using it, however when I tested it for 100,000 reads there was no difference to -Bit(rhs,lhs).
But I wasnt confident that the "-" was intended and/or reliable.

This is the Read of 1 of the 48 x 8 bit ports.

Code: Select all

`InCount = 0If IOCtrl.BrdInstall(1) Then                           'if I/O board installed    For Port = 0 To 5                                  'A1 to C2        Cz = 0        For Az = 1 To 3                                'get average            Bz = Inp(IOCtrl.PortAddr(Port))'of            Cz = Cz + Bz                               '3 reads        Next        Az = Cz / 3        IOCtrl.PortByte(Port) = Az                     'Save the byte        For Bits = 0 To 7                               '            IOCtrl.PortBit(InCount) = Bit1(Az,Bits)'set Bit to 0 or 1            Led.State(InCount) = IOCtrl.PortBit(InCount)'update Led            InCount += 1                                'next bit         Next    Next PortEndIf`

I basically put that in a Select case, and increment the case to read 8 boards. That way it only reads 1 board for each program loop.

Regards
Eclipzer
Posts: 432
Joined: Oct 01, 2005 10:50
Location: Maryland
Contact:
You might be wondering why -1 is returned instead of 1, but it's because -1 is a standard BASIC value for True. It's the number you get if you set all the bits in a signed integer, while 0 is what you get if you clear all the bits, and you can easily flip between the two values using the NOT operation.

Isn't this true of most programming languages, for the very reasons stated?
Sisophon2001
Posts: 1704
Joined: May 27, 2005 6:34
Location: Cambodia, Thailand, Lao, Ireland etc.
Contact:
This is my understanding.

- In most languages TRUE = 1. For example C.
- In old versions of BASIC TRUE = -1
- Most languages evaluate 0 as FALSE and <> 0 as TRUE in expressions, regardless of the value used for TRUE. This includes both BASIC and C.
- In some languages TRUE and FALSE are BOOLEAN variables, which might or might not evaluate to numerical equivalents.

Read up on the difference between logical and bitwise OR, AND and NOT to get a better understanding. I find it difficult to explain further.

Garvan
counting_pine
Posts: 6190
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs
Eclipzer wrote:
You might be wondering why -1 is returned instead of 1, but it's because -1 is a standard BASIC value for True. It's the number you get if you set all the bits in a signed integer, while 0 is what you get if you clear all the bits, and you can easily flip between the two values using the NOT operation.

Isn't this true of most programming languages, for the very reasons stated?
Well, most (for a given value of "most") programming languages have a proper, non-bitwise NOT operator for working with conditional expressions.

For example, C usually uses 1 for TRUE. It has the '!' operator which returns 1 for a zero value and 0 for a non-zero value. (For bitwise NOTs, it also has the '~' operator.)

Some languages have a more sophisticated system, that don't even consider TRUE/FALSE as numeric values. In these, most values of most types (e.g. 1, 0, "foo", {a, b, c} )will evaluate as TRUE, while FALSE might be something like a specific FALSE object, or an empty list, or Null or something like that.
Dinosaur
Posts: 1330
Joined: Jul 24, 2005 1:13
Location: Hervey Bay
Contact:
Hi all

I have taken two days now to isolate an exception that happens in Dos, but not in Windows.
I took counting_pine's suggestion and used the macro bit1 to do the following.

Code: Select all

`For Bits = 0 To 7 'Az holds value from port    IOCtrl.PortBit(IOCtrl.InCount) = Bit1(Az,Bits)    Led.State(IOCtrl.InCount) = IOCtrl.PortBit(IOCtrl.InCount)    IOCtrl.InCount += 1Next`
I put this into a Select Case 1 of 8, so that I dont read 8 boards all at once. This works when I compile for Win.
When I compile for Dos, I get an exception as soon as the program starts.
I isolated it to the line with the Bit1 macro. If I rem out 6 of the 8 cases, then there is no exception. The moment I read a third it bombs out.
By remming out the line with Bit1 on all 8 cases, I can read without an error. So, I wrote a long hand version of what the Macro does.

Code: Select all

`Shifter = &b00000001For Bits = 0 To 7    If (Az And Shifter) > 0 Then IOCtrl.PortBit(IOCtrl.InCount) = 1 Else IOCtrl.PortBit(IOCtrl.InCount) = 0   Shifter = Shifter Shl 1    Led.State(IOCtrl.InCount) = IOCtrl.PortBit(IOCtrl.InCount)        'update Led    IOCtrl.InCount += 1Next`
This does not cause an exception, and logically should do the same. However the question is why can I run this in Win witout errors, and why can I runonly two cases without an error in Dos.

Is it the repeated calling of the macro that corrupts ?
There doesnt appear to be much of a penalty in time for the long hand code.

Regards
marcov
Posts: 2929
Joined: Jun 16, 2005 9:45
Location: Eindhoven, NL
Contact:
Sisophon2001 wrote:- Most languages evaluate 0 as FALSE and <> 0 as TRUE in expressions,
regardless of the value used for TRUE. This includes both BASIC and C.

In general this is typically a C thing. And descendants. TRUE should not be anything (unless heavily typecast).

Most languages _store_ 0 and 1 for false and true, and values 2..2^(8*sizeof(booltype))-1 are typically undefined.