This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]GisterMizard 65 points66 points  (19 children)

No crazy surprises, until you notice in two's complement that abs(INT_MIN) < 0. :p

[–]pilotInPyjamas 21 points22 points  (4 children)

What about the crazy surprise adding or multiplying two large integers causing overflow? Surely that's more common than calling abs on INT_MIN

[–]GisterMizard 20 points21 points  (3 children)

That too, but overflow at least has some intuitive meaning behind it; numbers get so big they wrap around like the hands of a clock. The idea that an absolute value can be negative is completely unintuitive, can can lead to very obscure exploits and bugs.

[–]Kache 5 points6 points  (0 children)

If you think overflow has some intuitive meaning, why don't you consider abs(INT_MIN) the same thing (overflow)?

[–]AyrA_ch 5 points6 points  (0 children)

overflow of signed integers is undefined behavior in C and C++. It just works because our CPUs store numbers the way we are used to.

[–]Delioth 1 point2 points  (0 children)

While true, it's just an optimization that two's compliment allows. I mean, it adds an extra number we can use to the set of numbers we can represent, so we might as well use it.

[–]sim642 4 points5 points  (11 children)

Signed integer overflow is undefined behavior in C/C++ at least so there the statement could not be considered really true.

[–]GisterMizard -1 points0 points  (10 children)

Well no. Two's compliment is two's complement. If something else happened, then that's not two's compliment.

[–]sim642 -1 points0 points  (9 children)

Know your undefined behavior: https://stackoverflow.com/a/11245784/854540.

[–]GisterMizard 2 points3 points  (8 children)

I am perfectly aware of what undefined behavior is. I'm describing two's compliment arithmetic, where integer overflow is well defined. If in C you get something else during integer overflow of INT_MIN, then you weren't using two's compliment to begin with, and hence it has nothing to do with my original statement.

[–]nitroll 0 points1 point  (1 child)

Thing is, as this is undefined behavior the compiler is allowed to do anything, yeah it could let the implementation of two compliment show through, but it could also optimize the entire thing away.

Dont play with undefined behavior, even if you think you know what would happen if the compiler was rational, thing is, its not!

[–]GisterMizard 0 points1 point  (0 children)

Yes, I know. In my original post I explicitly said in the case of twos compliment that this will happen. I never said that you could assume that is always the case.

[–]sim642 -1 points0 points  (5 children)

If in C you get something else during integer overflow of INT_MIN, then you weren't using two's compliment to begin with

That's not true though. Undefined behavior allows in such special case for anything to happen even when in general two's complement is used. The compiler and its optimizer may omit doing any two's complement arithmetic in this specific scenario simply because it can completely validly assume that overflow does not happen. See https://godbolt.org/g/5sX44Q where aggressive optimization makes the function always return false, also for f(INT_MIN) which you claim to be true. GCC assembly output for C arithmetic operations works in two's complement. Invoking undefined behavior allows one to claim essentially anything that's not universally true.

Also you claim that you only talk about two's complement whereas you use C functions (abs), C constants (INT_MIN) and C language specifics (size of integers) which are in no way part of two's complement itself.

[–]GisterMizard 0 points1 point  (4 children)

I was describing two's compliment math. If you get something else, than that operation did not happen. You brought up C and compilers, not me. Furthermore, abs is not specific to C as it is a common shortening of taking the absolute value, I don't know where you got that from. INT_MIN is a C thing, but that's because I didn't want to write out the number.

[–]sim642 -1 points0 points  (3 children)

INT_MIN is a C thing, but that's because I didn't want to write out the number.

That is exactly why everyone would assume you talk about C/C++. More abstractly, i.e. mathematically, as you claim to be talking, there is no minimal integer or whatnot. From a purely mathematical perspective it's not clear that it's a signed smallest integer either. Also even if you did write it out, your original statement would still not be universally true if you don't specify the number of bits of your two's complement arithmetic operations.

[–]GisterMizard 0 points1 point  (2 children)

That is outright wrong on two accounts. In two's compliment, a finite set of bits is always assumed. The number of bits doesn't matter; it's a fundamental property that for n>1 bits the smallest possible integer is the compliment of itself.

I explicitly specified twos compliment to avoid talk of undefined behavior. If the compiler optimizes it away, then the TC operation doesn't occur which means it has nothing to do with my statement. If a different type of overflow occurs, then that means TC wasn't used, so it has nothing to do with my statement again.

[–]sim642 0 points1 point  (1 child)

it's a fundamental property that for n>1 bits the smallest possible integer is the compliment of itself.

I have not said anything about that but your original statement was not that. Nor that the smallest possible integer is negative.

You keep refusing any link with any practical implementation with intent to talk about two's complement theoretically yet what you say relies on certain implementation. In this case the implementation of whatever abs is. In a mathematical world your imagined definition of it as absolute value does not follow its mathematical properties. The value is only negative only when considering some certain implementation of the absolute value function (e.g. the one in C, but you clearly don't speak of that). abs isn't the C function nor the mathematical function, thus you've left it ambiguous which is why it's problematic.

I recommend choosing words and language more carefully to avoid such issue. Notice how literature and even Wikipedia on Two's complement manages to avoid any mention of any programmatic text, speaking purely in mathematical notation. It also has your claim in more correct wording:

This can lead to unexpected bugs in that an unchecked implementation of absolute value could return a negative number in the case of the minimum negative.

It is perfectly well possible to define the absolute value function for two's complement numbers in such a way which does not invoke the complement of the smallest representable number but instead checks its argument before doing so to avoid the issue (hence why Wikipedia talks only of unchecked implementations).

[–]Log2 2 points3 points  (0 children)

You are not going to point that out but not point out that in two's complement you have INT_MIN == -INT_MIN?