last day (15 days later) » 

17:56
3
Q: Why do the later 18 bit PDPs include both ones' and two's complement?

OmarLThe PDP-1 is a ones' complement machine, and does some checks to make sure you (almost) never get negative zero. I'm struggling to think why anyone would want ones' complement arithmetic, but it was more popular in the past. Then the PDP-4 came along, (and the similar -7, -9 and -15). The -4 was ...

Strangely (since other sources support the claim that the PDP-4 supported both), Computer Engineering: A DEC View of Hardware Systems Design gives the impression that the PDP-4 only had two’s-complement (pages 141 and 142)!
Good question. I'd always supposed (without looking deeper) that it was some sort of transitional design.
Two's-complement machines that have a "add with carry" and "subtract with borrow" instructions can perform single-word one's complement arithmetic fairly easily. Does the PDP4 have instructions to perform ones'-complement operations directly, or does it merely provide enough facilities to allow them to be performed by adding a few extra instructions?
@supercat there are no add/subtract with carry instructions; there are dedicated instructions for one's complement add and two's complement add. (Subtraction may be synthesised by negating the accumulator first)
An important aspect could also be that one's complement addition and subtraction with end-around carry and borrow makes much more sense for bit-serial ALUs than for bit-parallel ALUs with carry-look-ahead, where this just can't be parallelized. So I'd imagine that contributed to the overall move from one's complement to two's complement. Though I am not sure if this already applied to the PDP-4.
17:56
A bit of editorializing. Twos complement makes more sense. It takes more logic to implement one's complement. And negative zero is easier to deal with in two's complement: it doesn't exist!
@dirkt: When using a bit-serial CPU, performing a single-pass two's-complement addition is easy. I suppose one could perform a single-pass one's complement addition if one produces two bits of output for each bit of the result and can retroactively decide which one to use once the entire operation is complete, but otherwise I don't see how one could efficiently process ones'-complement serially since the value of the last bit of input could affect the value of all bits of output.
@supercat "I don't see how one could efficiently process ones'-complement serially". Have a look at end-around carry.
@WalterMitty, Twos complement hardware makes more sense once you understand it. But, a sign/magnitude notation is a lot more obvious to anybody who hasn't yet heard about twos complement. The sign/magnitude notation is a lot closer to how we write numbers on paper. Maybe if we all grew up writing the integer that is one less than zero as 9̅9̅99, (i.e., in tens complement), then twos complement computing hardware would have caught on sooner.
A lot of clockwork works like that. Say, the odometer in a car goes up to all nines and then rolls over to 0. It's kind of, the obvious way to do it.
The IBM 7090 was a sign magnitude machine. I took a course on that before I got my hands on a PDP-1. The best way to get a grasp of twos complent is to think of a car odometer. 999,999 is minus one.
17:56
@dirkt: I said "efficiently". On a serial system, one could perform end-around-carry with minimal hardware if every value gets shifted through the adder twice, but that would take twice as long as using a two's-complement addition.
@SolomonSlow: IMHO, the nicest way to think about two's-complement is to think about how the lowest N bits of a number will behave if one doesn't know the value of the upper bits, and then generalize to infinite N. Subtract 0001 from any number whose last four bits are 0000 and one will get a number whose last four bits are 1111, and for any N subtracting 1 from 0 will yield a number whose last N bits are all ones. The logical generalization is thus to say that subtracting 1 from zero yields a value where all digits are 1.
@SolomonSlow: Two's complement representation condenses that by saying that all digits to the left of the leftmost digit have the same value as the leftmost digit. Ones' complement says that all digits to the left of the leftmost digit or right of the rightmost digits have the same value as the leftmost digit, so 1110 would represent ...1111110.1111... which would in turn equal ...1111111.0000...., i.e. -1. If floating-point values were viewed as ones'-complement [regardless of bit representation], that would allow bitwise operations to be meaningfully defined upon them.
@supercat "On a serial system, one could perform end-around-carry with minimal hardware if every value gets shifted through the adder twice, but that would take twice as long as using a two's-complement addition.". Yes, exactly. And that's what you wanted in old systems - you trade expensive hardware components for speed. And it doesn't make sense to do that with a parallel adder. So you just get rid of the one's complement. And one's complement was used for traditional reasons, not because it was faster or more efficient than two's complement - it never was.
@dirkt: While certain kinds of I/O could be simpler with ones'-complement than than two's-complement, I would find it curious that people would think it desirable to cut the speed of additions in half to accommodate that outside of scenarios where e.g. one wants to add readouts to a lot of registers. On a ones'-complement machine with a register that constantly outputs its state, one could add a double row of green and red lights and having positive numbers show up in green and negative numbers show up in red using just two transistors per bit, plus another two per register.
@dirkt: Thus, if one wanted to add such readouts on a machine with 16 registers, one could do so with a reasonable amount of circuitry. Displaying two's-complement numbers in that form would require much more circuitry per register. I can see some cases where that simplified I/O could be valuable, but otherwise I fail to see any real advantage to ones'-complement math to justify the added expense.
@supercat "people would think it desirable to cut the speed of additions in half" they don't. That's why everyone switched from one's complement to two's complement. "where one wants to add readouts to a lot of registers." I think that was never the main use case. Mechanical calculators used "nine's complement", because it's reasonably cheap in terms of gears (but you need to perform additional cranks). When binary computers came up, copying this was one obvious choice (sign bits were the other). Two's complement wasn't well understood. Once it was understood, everyone switched.
The Curta used ten's complement, but couldn't read out negative numbers directly. If one needs to have an adding machine which, when asked to compute the difference of two values whose last two digits are 12 and 32, must output either 80 or 20 based upon whether the final result was positive or negative, but when given 12 and 33 must output either 79 or 21, it will be necessary to run a separate carry propagation pass between the computation of those values and when they are output. Performing that pass with every operation is easier than storing values without performing that pass, but...
...then performing the carry propagation on a temporary register when outputting the values. Which brings up my point that the ease of outputting negative numbers is the only advantage that ones'-complement or nines'-complement would have over two's-complement or ten's-complement.

last day (15 days later) »