title: On the std::abs function
body: <p>Is the <code>std::abs()</code> function well defined for ALL arithmetic types in C++11 and will return <code>|x|</code> with no problem of approximation?</p>
  
  <p>A weird thing is that with g++4.7, <code>std::abs(char)</code>, <code>std::abs(short int)</code>, <code>std::abs(int)</code>, <code>std::abs(long int)</code> and <code>std::abs(long long int)</code> seem to return a double (on the contrary of : <a href="http://en.cppreference.com/w/cpp/numeric/math/abs">http://en.cppreference.com/w/cpp/numeric/math/abs</a>). And if the number is casted to a double, we could have some approximation error for very large number (like <code>-9223372036854775806LL = 2^63-3</code>).</p>
  
  <p>So do I have the guarantee that <code>std::abs(x)</code> will always return <code>|x|</code> for all arithmetic types ?</p>
  
  <p>EDIT : here is an example program to make some tests </p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;iomanip&gt;
  #include &lt;cmath&gt;
  #include &lt;typeinfo&gt;
  
  template&lt;typename T&gt;
  void abstest(T x)
  {
      static const unsigned int width = 16;
      const T val = x;
      if (sizeof(val) == 1) {
          std::cout&lt;&lt;std::setw(width)&lt;&lt;static_cast&lt;int&gt;(val)&lt;&lt;" ";
          std::cout&lt;&lt;std::setw(width)&lt;&lt;static_cast&lt;int&gt;(std::abs(val))&lt;&lt;" ";
      } else {
          std::cout&lt;&lt;std::setw(width)&lt;&lt;val&lt;&lt;" ";
          std::cout&lt;&lt;std::setw(width)&lt;&lt;static_cast&lt;T&gt;(std::abs(val))&lt;&lt;" ";
      }
      std::cout&lt;&lt;std::setw(width)&lt;&lt;sizeof(val)&lt;&lt;" ";
      std::cout&lt;&lt;std::setw(width)&lt;&lt;sizeof(std::abs(val))&lt;&lt;" ";
      std::cout&lt;&lt;std::setw(width)&lt;&lt;typeid(val).name()&lt;&lt;" ";
      std::cout&lt;&lt;std::setw(width)&lt;&lt;typeid(std::abs(val)).name()&lt;&lt;std::endl;
  }
  
  int main()
  {
      double ref = -100000000000;
      abstest&lt;char&gt;(ref);
      abstest&lt;short int&gt;(ref);
      abstest&lt;int&gt;(ref);
      abstest&lt;long int&gt;(ref);
      abstest&lt;long long int&gt;(ref);
      abstest&lt;signed char&gt;(ref);
      abstest&lt;signed short int&gt;(ref);
      abstest&lt;signed int&gt;(ref);
      abstest&lt;signed long int&gt;(ref);
      abstest&lt;signed long long int&gt;(ref);
      abstest&lt;unsigned char&gt;(ref);
      abstest&lt;unsigned short int&gt;(ref);
      abstest&lt;unsigned int&gt;(ref);
      abstest&lt;unsigned long int&gt;(ref);
      abstest&lt;unsigned long long int&gt;(ref);
      abstest&lt;float&gt;(ref);
      abstest&lt;double&gt;(ref);
      abstest&lt;long double&gt;(ref);
      return 0;
  }
  </code></pre>