32
votes

Another question asked about determining odd/evenness in C, and the idiomatic (x & 1) approach was correctly flagged as broken for one's complement-based systems, which the C standard allows for.

Do systems really exist in the 'real world' outside of computer museums? I've been coding since the 1970's and I'm pretty sure I've never met such a beast.

Is anyone actually developing or testing code for such a system? And, if not, should we worry about such things or should we put them into Room 101 along with paper tape and punch cards...?

9
I know this question is old, but anyone reading it should be aware that (x & 1U) is valid (note the U) for determining even/oddness even on ones-complement or sign/magnitude implementations.R.. GitHub STOP HELPING ICE
@R. Are you sure?: In 32-bit 1's comp, -1 is represented as 0xFFFFFFFE, so (0xFFFFFFFE & 0x00000001) = 0x00000000 = false.Roddy
@Roddy: Casting a negative signed integer is required to compute (MAX_INT+1- (-value)) on all systems. For systems which use two's-complement math, the result of the computation will have the same bit representation as the original signed integer, and many compilers will thus simply reinterpret the value without generating any code to operate on it. On systems with one's-complement or signed-magnitude computation, however, the compiler would have to generate code for the typecast to ensure defined behavior.supercat
@Supercat - Interesting, thanks! re: (MAX_INT+1- (-value)) - do you have a source for that? Is it only in C99 standard?Roddy
Wikipedia's article on signed number representations mentions that "the Unisys ClearPath Dorado series mainframes use ones' complement".Paul A. Clayton

9 Answers

15
votes

I work in the telemetry field and we have some of our customers have old analog-to-digital converters that still use 1's complement. I just had to write code the other day to convert from 1's complement to 2's complement in order to compensate.

So yes, it's still out there (but you're not going to run into it very often).

13
votes

This all comes down to knowing your roots.
Yes, this is technically an old technique and I would probably do what other people suggested in that question and use the modulo (%) operator to determine odd or even. But understanding what a 1s complement (or 2s complement) is always a good thing to know. Whether or not you ever use them, your CPU is dealing with those things all of the time. So it can never hurt to understand the concept. Now, modern systems make it so you generally never have to worry about things like that so it has become a topic for Programming 101 courses in a way. But you have to remember that some people actually would still use this in the "real world"... for example, contrary to popular belief there are people who still use assembly! Not many, but until CPUs can understand raw C# and Java, someone is going to still have to understand this stuff.

And heck, you never know when you might find your self doing something where you actually need to perform binary math and that 1s complement could come in handy.

10
votes

The CDC Cyber 18 I used back in the '80 was a 1s complement machine, but that's nearly 30 years ago, and I haven't seen one since (however, that was also the last time I worked on a non-PC)

10
votes

RFC 791 p.14 defines the IP header checksum as:

The checksum field is the 16 bit one's complement of the one's complement sum of all 16 bit words in the header. For purposes of computing the checksum, the value of the checksum field is zero.

So one's complement is still heavily used in the real world, in every single IP packet that is sent. :)

7
votes

I've never encountered a one's complement system, and I've been coding as long as you have.

But I did encounter a 9's complement system -- the machine language of a HP-41c calculator. I'll admit that this can be considered obsolete, and I don't think they ever had a C compiler for those.

7
votes

I decided to find one. The Unisys ClearPath systems have an ANSI C compiler (yes they call it "American National Standard C" for which even the PDF documentation was last updated in 2013. The documentation is available online;

There the signed types are all using one's complement representation, with the following properties:

Type                 | Bits | Range
---------------------+------+-----------------
signed char          |   9  |  -2⁸+1 ...  2⁸-1
signed short         |  18  | -2¹⁷+1 ... 2¹⁷-1
signed int           |  36  | -2³⁵+1 ... 2³⁵-1
signed long int      |  36  | -2³⁵+1 ... 2³⁵-1
signed long long int |  72  | -2⁷¹+1 ... 2⁷¹-1

Remarkably, it also by default supports non-conforming unsigned int and unsigned long, which range from 0 ... 2³⁶ - 2, but can be changed to 0 ... 2³⁶ - 1 with a pragma.

6
votes

We got off our last 1960's Honeyboxen sometime last year, which made it our oldest machine on site. It was two's complement. This isn't to say knowing or being aware of one's complement is a bad thing. Just, You will probably never run into one's complement issues today, no matter how much computer archeology they have you do at work.

The issues you are more likely to run into on the integer side are endian issues (I'm looking at you PDP). Also, you'll run into more "real world" (i.e. today) issues with floating point formats than you will integer formats.

5
votes

Funny thing, people asked that same question on comp.std.c in 1993, and nobody could point to a one's complement machine that had been used back then.

So yes, I think we can confidently say that one's complement belongs to a dark corner of our history, practically dead, and is not a concern anymore.

0
votes

Is one's complement a real-world issue, or just a historical one?

Yes, it still used. Its even used in modern Intel processors. From Intel® 64 and IA-32 Architectures Software Developer’s Manual 2A, page 3-8:

3.1.1.8 Description Section

Each instruction is then described by number of information sections. The “Description” section describes the purpose of the instructions and required operands in more detail.

Summary of terms that may be used in the description section:
* Legacy SSE: Refers to SSE, SSE2, SSE3, SSSE3, SSE4, AESNI, PCLMULQDQ and any future instruction sets referencing XMM registers and encoded without a VEX prefix.
* VEX.vvvv. The VEX bitfield specifying a source or destination register (in 1’s complement form).
* rm_field: shorthand for the ModR/M r/m field and any REX.B
* reg_field: shorthand for the ModR/M reg field and any REX.R