Live data from Hacker News

Signed Integers Are Two’s Complement

open-std.org

61–70 of 126 posts

Re: Signed Integers Are Two’s Complement

#61
post #23

Earlier quoted context omitted.

No? If x is 3, then (x * 2) / 2 is also equal to 3 (as per the GP) but (x & ~1 * 2) / 2 is equal to 0. (If you meant ((x & ~1) * 2) / 2, then that is equal to 2).

You are of course correct. Not only have I mistook precedence, but I confused the lower bit with the upper one where overflow occurs. So the compiler optimizable fix is something like: ((x & INT_MAX) * 2) / 2 = x

  ((x & (INT_MAX / 2)) * 2) / 2

?

Re: Signed Integers Are Two’s Complement

#63
post #61

Earlier quoted context omitted.

You are of course correct. Not only have I mistook precedence, but I confused the lower bit with the upper one where overflow occurs. So the compiler optimizable fix is something like: ((x & INT_MAX) * 2) / 2 = x

((x & (INT_MAX / 2)) * 2) / 2 ?

My version works up to x = INT_MAX and your version still fails for negative ints, so I don't see the benefit of restricting the range. Getting closer :)

Re: Signed Integers Are Two’s Complement

#64
post #59

> Naïve overflow checks, which are often security-critical, often get eliminated by compilers. This leads to exploitable code when the intent was clearly not to and the code, while naïve, was correctly performing security checks for two’s complement integers. This is the most critical aspect. We have enough trouble already without the compiler actually fighting against security because this would fail in a machine fr…

Isn't the quoted part 180 degrees wrong? Such code was not "correctly performing security checks", since it was undefined behaviour - two's complement or not. Which was the whole problem.

The checks were not correct for all possible representations. If the only representation were two’s complement, there could be fewer areas of undefined behavior, so simple and straightforward security checks would be much more likely to be correct.

(Unfortunately it sounds like this proposal has been revised to leave overflow behavior as undefined. That’s a biggie. Oh well)

Re: Signed Integers Are Two’s Complement

#65
post #59

> Naïve overflow checks, which are often security-critical, often get eliminated by compilers. This leads to exploitable code when the intent was clearly not to and the code, while naïve, was correctly performing security checks for two’s complement integers. This is the most critical aspect. We have enough trouble already without the compiler actually fighting against security because this would fail in a machine fr…

Isn't the quoted part 180 degrees wrong? Such code was not "correctly performing security checks", since it was undefined behaviour - two's complement or not. Which was the whole problem.

Don't leave out the last part: ...was correctly performing security checks for two’s complement integers.

More pedantically, they could have written: ...was correctly performing security checks if the standard had been limited to two’s complement integers. But that was clearly the intent.

Re: Signed Integers Are Two’s Complement

#66
post #50

> Naïve overflow checks, which are often security-critical, often get eliminated by compilers. This leads to exploitable code when the intent was clearly not to and the code, while naïve, was correctly performing security checks for two’s complement integers. This is the most critical aspect. We have enough trouble already without the compiler actually fighting against security because this would fail in a machine fr…

This got rejected in the next revision of this proposal. Naive overflow checks are still undefined.

Okay, then the proposal is already mostly useless.

Re: Signed Integers Are Two’s Complement

#67
post #3

I'm curious why some old architectures didn't use two's complement for signed numbers. What advantage did one's complement or signed magnitude have over two's complement?

The big one (for me) is that it's really annoying having one more negative value than positive value.

Most software doesn't handle this properly, they don't realise abs doesn't always return a positive number (as abs(INT_MIN)=INT_MIN), and many other similar problems.

In an ideal world, I would only use unsigned when you care about things like being able to use all bit representations, then have made the all-1s number something like NaN, for ints.

Re: Signed Integers Are Two’s Complement

#68

Earlier quoted context omitted.

Sign-magnitude for the significand, and offset-binary for the exponent. The reason for this odd combination is probably historical.

It's done so that the bits will compare the same way whether treated as float or int. (modulo NaNs and stuff)

That is only true for non-negative floating point numbers. It's still useful though.

Interestingly, posits as originally proposed do have this property (except for infinity).

Re: Signed Integers Are Two’s Complement

#69
post #51
post #45

The link is an outdated version r0, this is r2 (don't know if it's the latest) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p090...

The main change between [P0907r0] and the subsequent revision is to maintain undefined behavior when signed integer overflow occurs, instead of defining wrapping behavior.

And the joy I originally had is once again lost.

Re: Signed Integers Are Two’s Complement

#70

The real issue isn't that C doesn't have a standard int overflow, but that it's undefined. What they could have done is made it implementation defined , like sizeof(int), which depends on the implementation (hardware) but on the other hand isn't undefined behavior (so on x86/amd4 sizeof(int) will always be equal to 4).

The modern case for keeping signed overflow as UB is that it unlocks compiler optimizations. For example, it allows compilers to assume that `x+1>x`. If implementations are forced to define signed overflow, then these optimizations are necessarily lost. So implementation-defined is effectively the same as fully-defined.

I suppose the question is, which of these optimisations are actually useful for the compiler to do automatically? Yours is the example that's always thrown about, but it always seems like the kind of optimisation that the programmer should be responsible for.
Post reply on HN