2

I'm running the following

test.cpp

#include <iostream>
#include <limits>
#include <cstdlib>
using namespace std;

int main(int argc, char** argv) {
    long value = numeric_limits<long>::min();
    value = abs(value);
    cout << value << endl;
}

Depending on what computer I compile and run the program on, I'm getting different results.

Either I get:

abs(numeric_limits<long>::min())

Or I get:

numeric_limits<long>::min()

In the latter case, abs() doesn't seem to be performed. I'm wondering what accounts for this difference and how I should accommodate it. Should I compute abs() in a different way?

Misbah Khan
  • 372
  • 2
  • 3
  • 12
  • 2
    Please specify on which computer/compiler you got which result. With 2's complement, `-min()` cannot be represented. – Marc Glisse Apr 22 '15 at 21:52
  • If you print `numeric_limits::min()`, is the value that you would expect to get via `abs()` smaller than `numeric_limits::max()`? – Bill Lynch Apr 22 '15 at 21:56
  • similiar to [this](http://stackoverflow.com/questions/29808397/how-to-portably-find-out-minint-max-absint-min) question asked earlier? – Philipp Lenk Apr 22 '15 at 21:56

3 Answers3

2

In 2's complement (which is the integer representation used by most modern chips) there is always 1 more negative value than positive - e.g. signed char on most implementations runs from -128 to 127. What do you expect to get if you did -((signed char)-128) given 127 is the largest positive number that a signed char can represent?

You've got a similar issue with your (signed) long that -(most negative long) isn't representable and overflow happens. Overflow for signed integers is undefined so its unsurprising you get a weird result

Mike Vine
  • 9,468
  • 25
  • 44
2

A look at a reference for std::abs tells us what's going wrong:

Computes the absolute value of an integer number. The behavior is undefined if the result cannot be represented by the return type.

So anything can happen. It even explains below how that's the case for systems that use 2's complement for signed integers:

Notes

In 2's complement systems, the absolute value of the most-negative value is out of range, e.g. for 32-bit 2's complement type int, INT_MIN is -2147483648, but the would-be result 2147483648 is greater than INT_MAX, which is 2147483647.

If you're interested about the actual standard references it's in section 7.20.6/7.22.6 for the C99/C11 standard respectively, since the C++ only references the C standard for the functions in <cstdlib> (with some extra overloads).

Community
  • 1
  • 1
AliciaBytes
  • 7,300
  • 6
  • 36
  • 47
1

The reason you would get a negative number from this is because of the way computers read signed numbers, two's complement. If a number type holds 4 bits then the boundary numbers this type could be are 0111 = 7 and 1000 = -8. When you use the abs() function it flips the bits then adds one to negative numbers to make them positive. When you do this to the minimum number you get 1000 =>flip bits=> 0111 =>add one=> 1000 which is the same number.

argetlam5
  • 112
  • 2
  • 10