Can someone tell me why this doesn't work? (SOLVED)

New to FreeBASIC? Post your questions here.
Rev5
Posts: 26
Joined: Jun 04, 2014 22:28
Location: USA

Can someone tell me why this doesn't work? (SOLVED)

Postby Rev5 » Jul 16, 2014 23:03

In the code below why do unsigned variables not return as expected :

Code: Select all

# DEFINE FALSE 0
# DEFINE TRUE ( NOT FALSE )

DECLARE FUNCTION CHECK_UBYTE() AS UBYTE
DECLARE FUNCTION CHECK_BYTE() AS BYTE

DIM AS UBYTE UB = TRUE
DIM AS BYTE B = TRUE

IF CHECK_UBYTE() = TRUE THEN
    PRINT "CHECK_UBYTE() = TRUE"
ELSE
    PRINT "CHECK_UBYTE() = FALSE"
END IF
IF CHECK_BYTE() = TRUE THEN
    PRINT "CHECK_BYTE() = TRUE"
ELSE
    PRINT "CHECK_BYTE() = FALSE"
END IF
IF UB = TRUE THEN
    PRINT "UB = TRUE"
ELSE
    PRINT "UB = FALSE"
END IF
IF UB = CAST( UBYTE, TRUE ) THEN
    PRINT "UB = TRUE IF CAST( UBYTE, _ )
ELSE
    PRINT "UB <> TRUE IF CAST( UBYTE, _ )
END IF
IF B = TRUE THEN
    PRINT "B = TRUE"
ELSE
    PRINT "B = FALSE"
END IF
SLEEP

FUNCTION CHECK_UBYTE() AS UBYTE
    'RETURN FALSE
    RETURN TRUE
END FUNCTION

FUNCTION CHECK_BYTE() AS BYTE
    'RETURN FALSE
    RETURN TRUE
END FUNCTION
Last edited by Rev5 on Jul 17, 2014 4:12, edited 1 time in total.
Rev5
Posts: 26
Joined: Jun 04, 2014 22:28
Location: USA

Re: Can someone tell me why this doesn't work?

Postby Rev5 » Jul 16, 2014 23:17

I thought on a binary level that TRUE would be all 1s since FALSE is all 0s. I updated the first link with further checks including variables and not just function returns. I also did a check using Cast() that does work as expected. I'm still misunderstanding how unsigned variables work on a binary level in comparison to signed variables.
vdecampo
Posts: 2982
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Re: Can someone tell me why this doesn't work?

Postby vdecampo » Jul 16, 2014 23:21

NOT FALSE = -1

This is why unsigned is not working. You can define FALSE as zero and TRUE as anything else (positive if you want it to work with unsigned numbers).

-Vince
Rev5
Posts: 26
Joined: Jun 04, 2014 22:28
Location: USA

Re: Can someone tell me why this doesn't work?

Postby Rev5 » Jul 16, 2014 23:40

I'm still missing something... If false = 0 then all of its bits are zeroes, right? So doesn't true ( not false ) mean all of its bits are ones? Are unsigned variable bits handled differently than signed variable bits?
Rev5
Posts: 26
Joined: Jun 04, 2014 22:28
Location: USA

Re: Can someone tell me why this doesn't work?

Postby Rev5 » Jul 17, 2014 4:12

After digging through the manual I discovered the Bin() function and found out that my #define FALSE and TRUE are both 32 bits in length. After switching from the 8 bit Bytes to 32 bit Integers I had no problems. Better yet for this scenario both signed and unsigned Integers work.

Code: Select all

    # DEFINE FALSE 0
    # DEFINE TRUE ( NOT FALSE )

    DECLARE FUNCTION CHECK_UINTEGER() AS UINTEGER
    DECLARE FUNCTION CHECK_INTEGER() AS INTEGER

    DIM AS UINTEGER UI = TRUE
    DIM AS INTEGER I = TRUE

    IF CHECK_UINTEGER() = TRUE THEN
        PRINT "CHECK_UINTEGER() = TRUE"
    ELSE
        PRINT "CHECK_UINTEGER() = FALSE"
    END IF
    IF CHECK_INTEGER() = TRUE THEN
        PRINT "CHECK_INTEGER() = TRUE"
    ELSE
        PRINT "CHECK_INTEGER() = FALSE"
    END IF
    IF UI = TRUE THEN
        PRINT "UI = TRUE"
    ELSE
        PRINT "UI = FALSE"
    END IF
    IF UI = CAST( UINTEGER, TRUE ) THEN
        PRINT "UI = TRUE IF CAST( UINTEGER, _ )"
    ELSE
        PRINT "UI <> TRUE IF CAST( UINTEGER, _ )"
    END IF
    IF I = TRUE THEN
        PRINT "I = TRUE"
    ELSE
        PRINT "I = FALSE"
    END IF
    SLEEP

    FUNCTION CHECK_UINTEGER() AS UINTEGER
        'RETURN FALSE
        RETURN TRUE
    END FUNCTION

    FUNCTION CHECK_INTEGER() AS INTEGER
        'RETURN FALSE
        RETURN TRUE
    END FUNCTION
codeFoil
Posts: 255
Joined: Dec 22, 2011 4:45
Location: United States
Contact:

Re: Can someone tell me why this doesn't work?

Postby codeFoil » Jul 17, 2014 4:17

Try adding this somewhere in your source.

Code: Select all

Print Len(TRUE)


You'll find that the expression you've defined (NOT TRUE) is being evaluated as a 4 byte Integer.
When you cast -1 to a UBYTE, you do indeed have all 8 bits set, which equals 255, but you are comparing it to a 32 bit signed value with all bits set. That is definitely not equal to 255. Since you are comparing an Integer with a byte, the byte value must be coerced to an Integer, so your Boolean expression is equivalent to 255 = -1 which is never true.

Replace

Code: Select all

#DEFINE TRUE (NOT FALSE)

with

Code: Select all

CONST AS UBYTE TRUE = (NOT FALSE)

and you will see different results.

Edit: Awesome. You found your own answer before I could complete my reply.
Rev5
Posts: 26
Joined: Jun 04, 2014 22:28
Location: USA

Re: Can someone tell me why this doesn't work? (SOLVED)

Postby Rev5 » Jul 17, 2014 5:56

Thanks for taking the time to explain this. Now I know about Len() too. I don't use #define often but from the numerous examples of various code I've read through I've seen TRUE and FALSE almost always assigned that way.
counting_pine
Site Admin
Posts: 6225
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Can someone tell me why this doesn't work? (SOLVED)

Postby counting_pine » Jul 17, 2014 10:15

The main thing I would take away from this problem is: because 0 is uniquely false and all nonzero values are true, you should test for truth not by comparing against any True value, but against False (i.e. 0).
Also, if you are going to use Not, make sure your value is either 0 or -1.
Even 2^32-1 is not good enough, because it assumes 32-bit Integers. But any signed type can store -1, even bytes.

(A safer 'Not' is just to test for 'n=0'. This avoids signedness problems, and is closer in effect to C's '!'.)
Rev5
Posts: 26
Joined: Jun 04, 2014 22:28
Location: USA

Re: Can someone tell me why this doesn't work? (SOLVED)

Postby Rev5 » Jul 17, 2014 14:59

I know this thread has been solved more than a few times already, but I wanted to put this out there as well. Going back to my original problem of comparing variables of different bit size I applied the And operator in place of the Equals operator. This method works as well and below is the original code modified to work this way.

Code: Select all

# DEFINE FALSE 0
# DEFINE TRUE ( NOT FALSE )

DECLARE FUNCTION CHECK_UBYTE() AS UBYTE
DECLARE FUNCTION CHECK_BYTE() AS BYTE

DIM AS UBYTE UB = TRUE
DIM AS BYTE B = TRUE

IF CHECK_UBYTE() AND TRUE THEN
    PRINT "CHECK_UBYTE() = TRUE"
ELSE
    PRINT "CHECK_UBYTE() = FALSE"
END IF
IF CHECK_BYTE() AND TRUE THEN
    PRINT "CHECK_BYTE() = TRUE"
ELSE
    PRINT "CHECK_BYTE() = FALSE"
END IF
IF UB AND TRUE THEN
    PRINT "UB = TRUE"
ELSE
    PRINT "UB = FALSE"
END IF
IF UB AND CAST( UBYTE, TRUE ) THEN
    PRINT "UB = TRUE IF CAST( UBYTE, _ )"
ELSE
    PRINT "UB <> TRUE IF CAST( UBYTE, _ )"
END IF
IF B AND TRUE THEN
    PRINT "B = TRUE"
ELSE
    PRINT "B = FALSE"
END IF
SLEEP

FUNCTION CHECK_UBYTE() AS UBYTE
    'RETURN FALSE
    RETURN TRUE
END FUNCTION

FUNCTION CHECK_BYTE() AS BYTE
    'RETURN FALSE
    RETURN TRUE
END FUNCTION
counting_pine
Site Admin
Posts: 6225
Joined: Jul 05, 2005 17:32
Location: Manchester, Lancs

Re: Can someone tell me why this doesn't work? (SOLVED)

Postby counting_pine » Jul 17, 2014 23:59

There's no need to do 'AND TRUE' - instead you could just write e.g. 'IF B THEN'. I personally don't find it helps readability, but it's worth a mention. IF will treat any nonzero value as true.

Something like 'B AND -1', apart from potentially changing the type of B, will have no effect on its value. In fact the AND operation will be detected by the compiler and optimised out by the compiler, much like 'OR 0,' '* 1', '+ 0', etc.
Rev5
Posts: 26
Joined: Jun 04, 2014 22:28
Location: USA

Re: Can someone tell me why this doesn't work? (SOLVED)

Postby Rev5 » Jul 18, 2014 0:23

counting_pine wrote:In fact the AND operation will be detected by the compiler and optimised out by the compiler, much like 'OR 0,' '* 1', '+ 0', etc.


It took me a couple times reading this sentence for it to make sense. Thanks for bringing this information about the compiler to my attention :)
codeFoil
Posts: 255
Joined: Dec 22, 2011 4:45
Location: United States
Contact:

Re: Can someone tell me why this doesn't work? (SOLVED)

Postby codeFoil » Jul 19, 2014 0:10

Rev5 wrote:Now I know about Len() too.


I should point out that is would have been wise of me to use SizeOf() rather than Len().
SizeOf will return the memory size of the data type of an expression.
Len will return the same, unless the data type is a String, in which case it returns a character count.
Rev5
Posts: 26
Joined: Jun 04, 2014 22:28
Location: USA

Re: Can someone tell me why this doesn't work? (SOLVED)

Postby Rev5 » Jul 19, 2014 0:43

Ahh, string datatypes... That's a can of worms I haven't yet overwhelmed myself with :)

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 5 guests