-0 < 0 ?
Phil Pilgrim (PhiPi)
Posts: 23,514
I've discovered that, in Spin, $8000_0000 < 0 is true. So is -$8000_0000 < 0, as is || $8000_0000 < 0. $8000_0000 is that peculiarity of two's complement arithmetic that has a "value" of either 0, "-0", or -2147483648, depending on one's interpretation. (TV_Text prints is as "-0"; but, when entering "-0" in Spin, you get zero, of course, not $8000_0000). In my own programming, I've sometimes used $8000_0000 to represent "undefined", when it cannot be arrived at naturally.
On the one hand, this property of Spin can certainly be useful as a quick test for the sign bit, and I'm glad the interpreter doesn't waste cycles testing for this special case. On the other hand, I wonder if there are any, more purely mathematical, apps depending on Spin's purportedly signed arithmetic that could get in trouble because of it.
I've also noticed that the compiler gladly accepts 2147483649 ($8000_0001 in unsigned arithmetic) as a valid decimal number, which TV_Text prints as -2147483647. While it's plain that hex constants should be treated by the compiler as "sign-agnostic", I wonder, given that Spin uses signed arithmetic exclusively, whether an invalid decimal constant should be flagged with an error or warning. This stems from the fact that, when using hex constants, one is acknowledging a certain internal representation. With decimal constants, those details are hidden from view and easily overlooked by the unwary.
Whatever the case, these are the kinds of things CS students are trained to look out for when programming. I'm not necessarily unhappy with the way Spin handles (or ignores) these issues. But it pays to know (and be reminded occasionally) that they exist.
-Phil
On the one hand, this property of Spin can certainly be useful as a quick test for the sign bit, and I'm glad the interpreter doesn't waste cycles testing for this special case. On the other hand, I wonder if there are any, more purely mathematical, apps depending on Spin's purportedly signed arithmetic that could get in trouble because of it.
I've also noticed that the compiler gladly accepts 2147483649 ($8000_0001 in unsigned arithmetic) as a valid decimal number, which TV_Text prints as -2147483647. While it's plain that hex constants should be treated by the compiler as "sign-agnostic", I wonder, given that Spin uses signed arithmetic exclusively, whether an invalid decimal constant should be flagged with an error or warning. This stems from the fact that, when using hex constants, one is acknowledging a certain internal representation. With decimal constants, those details are hidden from view and easily overlooked by the unwary.
Whatever the case, these are the kinds of things CS students are trained to look out for when programming. I'm not necessarily unhappy with the way Spin handles (or ignores) these issues. But it pays to know (and be reminded occasionally) that they exist.
-Phil
Comments
Also, "sign-magnitude" arithmetic has a -0, which happens to be $8000_0000 (32-bit).
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 6/13/2008 6:40:51 PM GMT
Again, technically correct. I suppose if anything needs to change, it's probably TV_Text.
I plan to make that change in a subsequent version of TV_WText. I've also added a modified version of your broadcast video settings to it and am working on adding a provision for broadcast sound (and muting to eliminate the white noise when broadcasting video without sound). To do the latter, I needed to write some unsigned arithemetic routines in Spin, which is where all this got started.
-Phil
The main question is whether it's important enough to add extra code to check for the special case of $8000_0000 and output the appropriate string constant. Since "-0" will only be produced in the case of $8000_0000, that is actually a legitimate representation for the $8000_0000 in decimal and maybe nothing has to be changed except maybe a comment in the source code to that effect.
|| $8000_0000 < 0 is also incorrect. I imagine SPIN interprets it that way because the correct result cannot be represented as a 32-bit long. ||-$8000_0000 == +$1_0000_0000. 2's compliment is not symmetrical, so we have this special case for absolute value. In my opinion, SPIN should recognize this case and represent || $8000_0000 as being equivalent to zero, not < 0, since $1_0000_0000 represented as a long is 0.
But then again...the SPIN interpreter uses all available space in the cog, so a correction for this would be wishful thinking. As a result: "caveat codor" (let the programmer beware).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Post Edited (Ken Peterson) : 6/14/2008 5:03:08 PM GMT
As to fixing tv_text and other ".dec"-infested objects, I'm coming around to Mike's way of thinking: it's probably not worth the effort, so long as programmers are made aware of the anomaly.
In any event, number representations can mean pretty much whatever we — or the programming languages we use — say they mean, even if it runs against convention. If I were designing a computer language, I'd be tempted to let $8000_0000 mean "undefined" and initialize all variables to that "value". It's what could be also be returned by things like x/0, tan(90), etc. But for now, I'm content with the way Spin handles things, so long as it's documented.
-Phil
What Abs and Negate $8000_0000 should do is open to debate but returning $8000_0000 seems reasonable and consistent with other implementations I've experienced and that's what appears to be happening in the example cases given earlier.
Just so everyone knows, the Propeller's hardware is doing exactly what it was designed to do in this case.· It's not how Spin is interpreting it, it's not the fault of Spin's || operator implementation... the Propeller Assembly ABS instruction returns the same value.· It's simply being deterministic and returning the result in the same way it always does but, user-interpretation aside, in 2's compliment this happens to be the exception case·where there is no positive compliment, so the result in the smallest negative number possible in the given bit space.· If the same logic were applied to a 33-bit value, $8000_0000 would be positive, but $1_0000_0000 would be·the exception case.
TV_Text·has a minor bug in this respect as it's number·to string conversion method doesn't take this exception into consideration.···By the way, the Numbers object does convert this properly, but it also has a lot more code to provide many other conversion features that we're never intended for inclusion in the TV_Text object.
Take care,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Jeff Martin
· Sr. Software Engineer
· Parallax, Inc.
I think we can all agree that $8000_0000 has some weird properties:
1. It's its own negative (uniquely a property of zero in unbounded arithmetic).
2. Its absolute value is negative (a property of no number in unbounded arithmetic).
3. It's a negative number that, when decremented by one, becomes a large positive number (a property of no number in unbounded arithmetic).
We're not dealing in unbounded arithmetic but, rather, modular arithmetic, whose characteristics diverge from "real math" at the modular boundary. Frankly, I don't think it matters what we call $8000_0000, be it "-2147483648", "-0", "0", or "undefined". It's not a real integer, so we shouldn't expect it to behave like one. Consequently, I wouldn't even call its tv_text representation a "bug" necessarily, since "-0" (though at odds with convention) is as consistent with the math as anything else one could output.
Move along, folks. 'Nothing to see here.
-Phil