49

As we all no doubt know, the ISO C standard (and C++ as well, I think, though I'm more interested on the C side) allows three underlying representations of signed numbers:

  • two's complement;
  • ones' complement; and
  • sign/magnitude.

Wikipedia's entry states that sign/magnitude is used on the IBM 7090 from the 60s, and that ones' complement is used by the PDP-1, CDC 160A and UNIVAC 1100, all of which date back to the 60s as well.

Are there any other implementations of C (or underlying hardware) with these alternative representations, that have come out a little more recently than fifty years ago (and what are they)?

It seems a little wasteful to keep something in a standard for machines no longer in existence.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    Does "Yes, someone knows non-two's-complement implementations" qualify as an answer? :-) – Kerrek SB Sep 05 '12 at 08:11
  • 3
    @KerrekSB: Only if you can back that up with evidence... :-) – R.. GitHub STOP HELPING ICE Sep 05 '12 at 08:11
  • 1
    @KerrekSB: upadted the question with "and what are they" to make the point moot :-) – paxdiablo Sep 05 '12 at 08:13
  • 10
    Note that removing non-2's-complement from the standard would completely ruin my stock response to all "what do you think of this bit-twiddling extravaganza?" questions, which is to quickly confirm that they don't work for 1s' complement negative numbers. As such I'm either firmly against it or firmly in favour, but I'm not sure which. – Steve Jessop Sep 05 '12 at 08:31
  • 11
    See [Exotic architectures the standard committee cares about](http://stackoverflow.com/questions/6971886/exotic-architectures-the-standard-committee-cares-about) – Bo Persson Sep 05 '12 at 09:10
  • @SteveJessop I regret to inform you that the [most recent draft](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf), following document [N2412](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2412.pdf), now requires two's complement representation. – texdr.aft Mar 22 '21 at 02:46

2 Answers2

39

The most recent example I can find is the UNISYS 2200 series, based on UNIVAC, with ones-complement arithmetic. The various models were produced between 1986 and 1997 but the OS was still in active development as late as 2015. They also had a C compiler, as seen here.

It seems likely that they may still be in use today.

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 7
    Out of interest, what were Unisys 2200 *for*? Replacing worn-out Univacs running mission-critical legacy apps, or is there new development? – Steve Jessop Sep 05 '12 at 09:13
  • 2
    Unisys offered [hardware running OS2200](http://www.unisys.com/unisys/theme/index.jsp?id=1120000970018010225&pid=16000034) as late as last year (2011). – Bo Persson Sep 05 '12 at 09:14
  • 1
    According to Wikipedia, the latest version of [OS 2200](https://en.wikipedia.org/wiki/Unisys_OS_2200_operating_system) is from 2010. – Fred Foo Sep 05 '12 at 10:00
  • Good find. I've done some extra research to find that it does indeed have a C compiler, and adjusted your answer to suit. Hope you don't mind. Guess we won'y be petitioning INCITS to advise ISO on removal after all :-) – paxdiablo Sep 05 '12 at 14:06
  • 3
    The OS 2200's C compiler doesn't appear to be standards compliant in it's "ones complement mode", The maximum unsigned value (UINT_MAX) is `2^N-2`not `2^N-1`. It looks like this is done so that the 0x3FFFF or minus zero is not a valid value when you cast a signed to an unsigned int without changing the bit pattern. (C99 and C11 that is, it _may_ be compliant with C89 but only in an _there ain't no law against it_ manner, it's pretty obvious what an unsigned is expected to be. ) – user3710044 Apr 18 '15 at 15:57
  • It's too bad the standard provides no way to say "Within this context, I want the system to either behave like a X machine or refuse compilation if it can't". Such a design would make it possible for a system like the OS2200 to continue to support its existing code base but also make it possible to run code for other machines by e.g. using `unsigned` internally for all integer types, but having `int x,y; long z; ... if (x > y) z=x;` yield machine code equivalent to `if ((x + 0x8000u) > (y + 0x8000u)) z = (x + 0x8000u)-0x8000ul`, and generating similar code for right-shifts and divisions. – supercat Apr 30 '15 at 16:23
  • 2
    Even if the compiler was updated in 2015, it doesn't seem to be compliant with any standard past C89; among other things, it does not have any unsigned type longer than 36 bits. – supercat Nov 10 '16 at 19:40
  • @user3710044 Note that the C standard allows ones' complement. The maximum unsigned value is still not allowed though. – martinkunev Jul 08 '18 at 08:13
6

I don't have any conclusive evidence that none exist, but I've never seen one. To my knowledge, all non-twos-complement hardware was obsolete long before C was standardized.

Perhaps the best way to gather evidence would be to look for conflicting requirements and other outright bugs in the standard connected to non-twos-complement systems. If no such implementation has ever been created, it's likely there are oversights in the specification that would become apparent when somebody actually tries to make one.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 10
    Or to do this thoroughly: write a VM with minimal bytecode and that uses 1s' complement and/or sign-magnitude. Implement a GCC or LLVM backend for it if either of them has nominal support for that, or a complete C implementation if not. That both answers the question ("yes, I do now know of a non-2's-complement implementation") and gives an opportunity to file considered defect reports if the standard does have oversights. If any of the defects is critical then it's ammunition to mandate 2's complement in the next standard. – Steve Jessop Sep 05 '12 at 08:15
  • 9
    @SteveJessop: that's a cool approach but it might be slightly more work than usually goes into answering a SO question ;-) – Joachim Sauer Sep 05 '12 at 08:17
  • 3
    @JoachimSauer: I concede that I personally can't be bothered with it. – Steve Jessop Sep 05 '12 at 08:17
  • 1
    The standard nominally allows negative zero to exist for such implementations, but I seem to remember there being some amusing interaction of bitwise not and another operator that made the resulting requirements extremely costly to satisfy, if not impossible... Reporting that issue, if one can find it again, wouldn't be enough to kill non-twos-complement, but it might be sufficient to kill the allowance for negative zero. – R.. GitHub STOP HELPING ICE Sep 05 '12 at 08:18
  • 1
    IIRC the standard intends that if your hardware has a negative 0, but you don't want to support it properly in C, you can do nothing. If you "officially" don't have a negative 0 then bit operations that generate that representation have UB. So returning a trap representation that mostly behaves like a `0` but not quite correctly is fine. Well, it conforms. The programmer who accidentally writes `~i` without checking `(i != 0) && (i != INT_MAX)` might not think it's fine. I'd kind of prefer to remove the requirement that bit operations can be applied to signed types, if we're wishing ;-) – Steve Jessop Sep 05 '12 at 08:22
  • @SteveJessop: good luck writing a GCC backend for a non-2's-complement machine. You'd have to rewrite most of the middle-end, as well, and if you wanted to run it natively on that target then the entire compiler would probably need a once-over (not to mention the rest of the OS). – ams Sep 05 '12 at 09:03
  • 2
    @ams: my target has no OS, it's just some toy bytecode interpreter. But if GCC assumes 2's complement then sure, it's no good for my hypothetical project. – Steve Jessop Sep 05 '12 at 09:11
  • 4
    I would guess GCC assumes both twos complement and 8-bit bytes at the very least. Well, rather than "assumes", I would just say "defines", since it's up to the compiler to define these concepts. Even on a machine that was intended to do sign/mag or ones complement, the compiler can easily choose to provide a twos complement environment merely by using the unsigned arithmetic instructions instead of the signed ones... – R.. GitHub STOP HELPING ICE Sep 05 '12 at 14:44
  • There's enough inconsistencies in the standard for real machines that this approach would not really indicate anything... – M.M Aug 03 '15 at 03:54
  • 1
    @MattMcNabb: Citation? We're all aware of minor things where there's a general consensus on what the intended meaning was, or at least how real-world compilers should interpret it. I suspect the inconsistencies will be a lot more show-stopping for non-twos-complement and will come up immediately when you try to work out behaviors for stdio and string functions. – R.. GitHub STOP HELPING ICE Aug 03 '15 at 15:29