By paxdiablo

2012-09-05 07:58:52 8 Comments

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.


@Mike Seymour 2012-09-05 09:07:46

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.

@Steve Jessop 2012-09-05 09:13:49

Out of interest, what were Unisys 2200 for? Replacing worn-out Univacs running mission-critical legacy apps, or is there new development?

@Bo Persson 2012-09-05 09:14:16

Unisys offered hardware running OS2200 as late as last year (2011).

@Fred Foo 2012-09-05 10:00:02

According to Wikipedia, the latest version of OS 2200 is from 2010.

@paxdiablo 2012-09-05 14:06:55

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 :-)

@phuclv 2014-06-20 03:15:07

@larsmans as of now, the latest OS2200 is from 2013

@user3710044 2015-04-18 15:57:07

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-2not 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. )

@supercat 2015-04-30 16:23:45

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 2016-11-10 19:40:09

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.

@martinkunev 2018-07-08 08:13:29

@user3710044 Note that the C standard allows ones' complement. The maximum unsigned value is still not allowed though.

@R.. 2012-09-05 08:11:08

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.

@Steve Jessop 2012-09-05 08:15:59

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.

@Joachim Sauer 2012-09-05 08:17:10

@SteveJessop: that's a cool approach but it might be slightly more work than usually goes into answering a SO question ;-)

@Steve Jessop 2012-09-05 08:17:37

@JoachimSauer: I concede that I personally can't be bothered with it.

@R.. 2012-09-05 08:18:06

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.

@Steve Jessop 2012-09-05 08:22:13

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 ;-)

@ams 2012-09-05 09:03:27

@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).

@Steve Jessop 2012-09-05 09:11:44

@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.

@R.. 2012-09-05 14:44:13

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...

@M.M 2015-08-03 03:54:22

There's enough inconsistencies in the standard for real machines that this approach would not really indicate anything...

@R.. 2015-08-03 15:29:32

@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.

Related Questions

Sponsored Content

7 Answered Questions

[SOLVED] Exotic architectures the standards committees care about

  • 2011-08-07 09:30:54
  • ybungalobill
  • 11063 View
  • 144 Score
  • 7 Answer
  • Tags:   c++ c architecture

9 Answered Questions

0 Answered Questions

When are bitwise operations undefined in C?

8 Answered Questions

2 Answered Questions

1 Answered Questions

4 Answered Questions

[SOLVED] Are there well-known "profiles" of the C standard?

  • 2011-08-24 13:46:44
  • Henning Makholm
  • 373 View
  • 12 Score
  • 4 Answer
  • Tags:   c language-lawyer

3 Answered Questions

Sponsored Content