display | more...

BASIC used to be everyone's favorite toy programming language. It's simple and allows basic algorithms to be implemented with minimal effort. Not a whole lot of trouble for anything in the language's built-in capabilities. Of course, if you want to head up the spectrum towards advanced programming, you probably want to ditch BASIC's less-than-modern style before too long.

Now suppose you're just discovering the vagaries of the if statement in a program you've written and you're using a classic troubleshooting method -- entering PRINT statement to spot a comparison gone awry. Examining this comparison is trivial in any other language. Depending on what language you're using, the result of printing a straight comparison will yield the equivalent of true or false. In some languages, you'll get a straight 0/1; in Java, you'll get true/false; in Lisp-like languages, you're returned #f/#t.

But the result of this statement in BASIC:

PRINT 4 < 5

is -1.

-1? It's disconcertingly backwards. How could true be a negative one? The answer lies in BASIC's complete disinterest in consistent typing.

In two's complement binary arithmetic, a developed and logical number wheel arises, whereby the leftmost bit of the number indicates the sign, and the rest of the bits designate the distance from either zero or the floor of the wheel (i.e., -(2^n-1), all the bits except the sign bit.) Likewise, programming languages have signed and unsigned numbers. Even though a boolean value is likewise represented in a byte as 00000000 or 00000001, its actual integer value is unsigned, producing 0 or 1. No one would really ever think to treat a single bit as signed or unsigned; the bit would simultaneously be the sign bit and the distance from the floor, so its derivation would be generally irrelevant.

To reverse the sign of a number in two's complement, you flip all the bits and add 1. For instance, a full byte designating one is 00000001. You flip all the bits, yielding 11111110, and add one. -1 is represented as 11111111. But suppose you only have one bit -- the ideal treatment for a boolean value. -1 is represented as the negation of 1. The reverse of 1 is 0, and 0 + 1 is 1. The value of the bit "1" actually evaluates to -1, and BASIC never bothers to treat it as unsigned. So trying to PRINT the boolean value true actually yields -1. It is a signed boolean, something of a curiosity in that you have no ability to specify it should be otherwise.

Actually, the reason that BASIC represents True as -1 is pretty simple, and has nothing to do with whether or not the integer is signed or not (BASIC doesn't have unsigned integers, so that question is pretty moot). The reason BASIC does it is because of it's very relaxed coercion rules.

In BASIC, when coercing numbers for a boolean expression, any non-zero number is coerced to True, and zero is coerced to False. So, for instance, the following works fine:

If 4 Then Print "You betcha."

Now, BASIC also has no concept of boolean operators: AND, OR, and NOT are all bitwise operators. For NOT, especially, this can create a gotcha that trips up those not expecting it.

If 4 Then Print "You betcha."
If Not 4 Then Print "You betcha."

Both of these statements will print. Why? Well, 4, as a signed integer, looks like this:

00000100

Not 4, then, looks like this:

11111011

Which is equivalent to 251. And 251 is, of course, coerced to true if you use it in a boolean expression. So, to avoid the problem of having (Not True) = True, the numeric value of True has to be such that (Not True) = False. Since False is:

00000000

True must therefore be:

11111111

Which is, when signed, -1. (Were it unsigned, it would be 255, which is not exactly a whole lot more intuitive)

Log in or register to write something here or to contact authors.