home | list info | list archive | date index | thread index

Re: [OCLUG-Tech] Double checking re: twos complement & signed types ??

  • Subject: Re: [OCLUG-Tech] Double checking re: twos complement & signed types ??
  • From: "Brenda J. Butler" <bjb [ at ] linuxbutler [ dot ] ca>
  • Date: Thu, 20 Sep 2007 18:14:16 -0400
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