Hacker News new | ask | show | jobs
by FullstakBlogger 1086 days ago
Why does starting with ones' compliment make things easier? IMV, it makes it more confusing, because two's compliment seems like an arbitrary leap that happens to work.

If you're tasked with mapping a subset of bit-states to negative numbers, it's intuitively obvious that there's already a state that yields 0 when you add 1 to it, as long as you wrap on overflow. With four bits that's 1111. That's a great representation of -1.

If you want to get 0 by adding 2, you'd have to start from 1110, and so on.

Just because the top bit can be used to identify a negative number when you use up half the states, doesn't mean it should be thought of as a logical flag. That's how you invent ones' compliment.

I think of ones' compliment as a logical encoding, and two's compliment as an arithmetic encoding, and it shows in how easy negation is in ones' compliment, and how easy arithmetic is in two's compliment.

The fact that everyone tries to teach them as if one is a precursor to the other is what's confusing.

1 comments

It's really, because it's were we came from. Early computers used ones' complement and there had to be extra circuitry to fix the -0 issue. Two's complement was explicitly introduced to fix this. – So how do you explain a fix without mentioning the bug?

Notably, ones' complement is easy to operate on, when reading values from blinkenlights or entering them via toggle switches, especially with octal grouping in triplets of bits. Which isn't that true for two's complement representation, as it is less intuitive (and digit positions shift with negative numbers). And the introduction of two's complement roughly coincides with operator consoles and switches becoming less important.

(It's true, if two's complement does work, you must be able to express and generalize this in terms of number theory, but this doesn't mean that it really stands on its own feet in terms of raison d'être.)

Regarding the sign-bit, this is an essential feature: checking the sign-bit for branching (or skipping) is the most basic approach to Turing complete computing. (Turing, the man himself, thought it is all there should be.) And it's also an essential bridge between numeric and logic computing, e.g., when we shift or rotate a bit vector to inspect the bit now in sign position.

There's also signed-magnitude, which Burroughs used.

Burroughs even had a unified floating point and integer representation. 48-bit floats had a sign, an exponent sign, an exponent, and a mantissa. The binary point was at the low end of the mantissa, and if both inputs had a zero exponent and the result could be represented with a zero exponent, it would be. No need for a float/integer distinction in programs.