Many aspects of the language standard are as they are because the Standards Committee has been extremely loath to forbid compilers from behaving in ways that existing code may rely upon. If code exists which would rely upon one's complement behavior, then requiring that compilers behave as though the underlying hardware uses two's complement would make it impossible for the older code to run using newer compilers.
The solution, which the Standards Committee has alas not yet seen fit to implement, would be to allow code to specify the desired semantics for things in a fashion independent of the machine's word size or hardware characteristics. If support for code which relies upon ones'-complement behavior is deemed important, design a means by which code could expressly demand one's-complement behavior regardless of the underlying hardware platform. If desired, to avoid overly complicating every single compiler, specify that certain aspects of the standard are optional, but conforming compilers must document which aspects they support. Such a design would allow compilers for ones'-complement machines to support both two's-complement behavior and ones'-complement behavior depending upon the needs of the program. Further, it would make it possible to port the code to two's-complement machines with compilers that happened to include ones'-complement support.
I'm not sure exactly why the Standards Committee has as yet not allowed any way by which code can specify behavior in a fashion independent of the underlying architecture and word size (so that code wouldn't have some machines use signed semantics for comparisons where other machines would use unsigned semantics), but for whatever reason they have yet to do so. Support for ones'-complement representation is but a part of that.
x & 0xF
return a value between 0 and 15 in a sane manner is another. – Actionx & 0xF
possibly not return a value between 0 and 15? C++ does require a binary representation, it just doesn't specify the negative representation. – Saddleclothx % 16
to do (i.e. the mathematical definition of "mod"). – Actionx % 16
and let the optimizer do the transform if it is valid. – Trevorx % 16
acts like mathematical mod! – Action%
is now guaranteed not to act like mathematical modulus for negative numbers, since/
is now guaranteed to truncate towards zero. – Chunx & 0xf
gives you if your integers are 2's complement. If they aren't, you need((unsigned int)x) & 0x0f
instead. – Chunx & 0x0f
doesn't preserve equivalence classes in one's complement or sign-magnitude, when the input is negative. But it does give a non-negative number, and the remainder, given a negative input, is negative, even for two's complement, sox & 0x0f
doesn't yield remainder with a negative argument, ever. That's why I'm surprised this came up in a discussion which apparently concerns representation of negative numbers. – Saddlecloth