Bill, On Wed, Sep 19, 2007 at 01:20:35PM -0400, William Case wrote: Basically, you missed out this part of what I (and Bart) said: > > A signed integer and an unsigned integer are not treated differently > > by the machine. When they get added together, or subtracted > > or whatever, they have exactly the same effect upon the accumulator > > and the status register (NCZV). Signed integers and unsigned integers are treated the same by the ALU. The ALU does not care if a given number in the accumulator is "signed" or "unsigned". It will treat it the same way. CPU's don't care about signed vs unsigned. Compilers make that distinction. > > It is what the C compiler does with the contents of the accumulator and > > the status register that makes it signed or unsigned. > > > > I gather you are saying, that if there is a subtraction operation in > some C code, it is the *compiler* that alters the value of the number to > be subtracted (or negated) into it's two's complement binary > representation and that is the value stored in memory. ?? Well, the compiler does arrange for the right representation to be given for the variable or constant in question. But it doesn't do it by looking at the number, assigning an "absolute" value to it, and then if it's negative changing the number to its two's complement. > Once stored as a two's complement representation, when fetched for use > in the ALU, the ALU just performs a normal add instruction. Well, the part after the comma is correct. The part before the comma, is, umm, well all the numbers are stored as two's complement. > I.E. For me, all I would probably ever use is an unsigned integer (or > short or float or double) and the subtract operator -- correct?? No ... If you want to do away with signed integers, then program in assembly. You can handle the interpretation of the numbers yourself (eg, when subtracting a big positive number from a small positive number). > Have I got the above right? Usually, when you feel like you're trying to nail down flies and missing all the time, you have the wrong mental model. (Warning: use fixed-width font to make any sense out of the following:) | the same representation| -8 -7 -6 -5 -4 -3 -2 -1 | 0 1 2 3 4 5 6 7 <-- (signed) (unsigned) -> 0 1 2 3 4 5 6 7 | 8 9 10 11 12 13 14 15 1 1 1 1 1 1 1 1 | 0 0 0 0 0 0 0 0 | 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 | 0 0 0 0 1 1 1 1 | 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 | 0 0 1 1 0 0 1 1 | 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 | 0 1 0 1 0 1 0 1 | 0 1 0 1 0 1 0 1 (note, binary representation of each number is in a vertical column below the number.) There are only 2^4 values you can put in 4 bits - the difference in signed and unsigned is in how you interpret those values. The values of 0-7 for both signed and unsigned are the same. This is the part of the signed and unsigned number range that overlaps. Note that the column for -1 is identical to the one for 15 Note that the column for -2 is identical to the one for 14 Note that the column for -3 is identical to the one for 13 etc. When you add 0001 to 0111, you get 1000 and the status register shows (N:1 Z:0 C:0 V:1 ) Depending on what the compiler decides, that can be interpreted as 8 or -8 When you add 0001 to 1111, you get 0000 and the status register shows (N:0 Z:1 C:1 V:0 ) Zero is always 0. But, you might have added 1 to 15, or added 1 to -1. "Two's complement" is another name for the ascii-art picture I drew, and the fancy formula they give you is just a way to calculate what the picture shows. The status bits show: N: when the high bit is set in the result Z: when the number is all zeroes in the result C: when the arithmetic "carries" as an unsigned (goes over the 0 -> -1 boundary or over the 15 -> 0 boundary) V: when the arithmetic "overflows" as a signed (goes over the -8 -> -9 boundary or over the 7 -> 8 boundary) Hope this helps. cheerio, bjb