SPIN: A byte or word can never equal -1 and TRUE
dbpage
Posts: 217
in Propeller 1
I have some projects that never worked right until I finally got it through my thick head that a byte or word can never equal -1 and TRUE. TRUE is defined to be -1.
Under normal circumstances, equating a byte or word to a long will truncate and assign the least significant 8 or 16 bits of the long to the byte or word. For example:
I would love to read your comments.
Under normal circumstances, equating a byte or word to a long will truncate and assign the least significant 8 or 16 bits of the long to the byte or word. For example:
Byte: C := -1 ' assign 255 to C Byte: C := TRUE ' assign 255 to C Word: C := -1 ' assign 65535 to C Word: C := TRUE ' assign 65535 to CThe following logical tests can never be true when C is a byte or word:
C == -1 C == TRUEThe following logical tests can be true when C is a byte or word:
Byte: C == 255 Word: C == 65535The least significant 8 or 16 bits of -1 and TRUE are equal to 255 (byte) and 65535 (word), but in logical tests, a byte or word can never equal -1 and TRUE.
I would love to read your comments.
Comments
If you said "if C == TRUE" then it would always fail but you can just as easily say "if C" without the condition as the "if" is equivalent to a "jump if zero" and doesn't care about the actual value other than whether it's zero or not zero, or is that FALSE ?
You can force Spin to sign extend the byte or word for the logical test:
Byte: if ~C == TRUE
Word: if ~~C == TRUE
But as others already said: All values <> zero are defined as true, not only -1. So comparing to one of the many possible TRUE values makes not much sense.
Andy
Both work. It's a silly construct, but, you're right, when C := TRUE, the logical tests ~C == TRUE and ~~C == TRUE evaluate to be TRUE. Same when C := -1 (because TRUE is -1).
Curious, but when C is defined as a word and C := TRUE, both ~C == TRUE and ~~C == TRUE evaluate to be TRUE: and The point of my post is to be conscious of type mismatch. SPIN lets us be lazy in some instances, but we must be on our toes in other instances. The compiler doesn't protect us with type mismatches.
This is where I get into trouble. With regard to "All values <> zero are defined as true, not only -1", the Propeller manual says for AND and OR, "..the value of X is promoted to TRUE if it is non-zero, then is compared with TRUE and the Boolean result (TRUE / FALSE, -1 / 0) is stored back in X." I erroneously extended that statement to logical tests other than AND and OR.
You smarter people know better!
"==" is a numerical test, not a logical test.
~C sign extends from bit 7 and ~~C sign extends from bit 15, that is: all higher bits are set to the state of bit 7 or 15.
So if you set a word variable to TRUE, all the bits from 0 to 15 are set, and a signextend from bit 7 also gives -1. If you set a byte variable to TRUE, only bit 0..7 get set, and a sign extend from bit 15 will result in 255, because bit 15 is low.
I like the lazyness of Spin in respect to types, it does just what I code. While the type checking of C compilers is really annoying sometimes.
Andy
All this time I thought "if C == TRUE" was a logical test, and I now know it's a mathematical operation.
Hence, Ariba's strategy is the spot on. Without sign extending (~C for byte, ~~C for word), a byte or word can never equal -1 and TRUE.
Thank you all for the clarification. It was fun!
The correct definition is that FALSE is defined as 0 and TRUE is defined as NOT FALSE.
So instead of "if C==TRUE" check "if C<>FALSE"
Enjoy!
Mike
Does "NOT FALSE" mean anything that is not 0.
Or does it mean the logical bitwise NOT of zero. Which is -1 in two-complement representation?
Or even, given that FALSE is 0 does it mean TRUE is just 1?
Every language I have ever worked with has made a mess of this.
SPIN promotes non-zero values to -1 *only* for AND, OR and NOT. For IF, UNTIL and WHILE (for example), bytes and words can never equal TRUE and -1 without sign extending. This is because SPIN defines TRUE to be equal to -1, and treats all bytes and words as unsigned.
That leaves us with zero or non-zero as the only tests for operations, except AND, OR and NOT in SPIN.
Regarding bitwise "!", I got into trouble thinking that when X is non-zero, !X will always be zero. !X is zero only when X = TRUE or X = -1. In all other cases, the bits are toggled and a non-zero X will remain non-zero.
While it's true that 0 and 1 would have been better choices in most cases, there is no good choice given the absence of any typing in the language.
Given the untyped nature of the language, it's best to not think of relational operators as yielding Boolean results as there is no Boolean type. Similarly, and, or and not are also best considered as arithmetic operators and if is best considered to be if-not-zero.
That perversion is the only consistent approach that will lead to understanding of why the perversion of "if 3" doesn't cause semantic errors at compilation time.