views:

488

answers:

4

Hi, here is a quite simple question(I think), is there a STL library method that provides the limit of a variable type (e.g integer) ? I know these limits differ on different computers but there must be a way to get them through a method, right?

Also, would it be really hard to write a method to calculate the limit of a variable type?

I'm just curious! :)

Thanks ;).

+26  A: 

Use numeric_limits:

// numeric_limits example
// from the page I linked
#include <iostream>
#include <limits>
using namespace std;

int main () {
  cout << boolalpha;
  cout << "Minimum value for int: " << numeric_limits<int>::min() << endl;
  cout << "Maximum value for int: " << numeric_limits<int>::max() << endl;
  cout << "int is signed: " << numeric_limits<int>::is_signed << endl;
  cout << "Non-sign bits in int: " << numeric_limits<int>::digits << endl;
  cout << "int has infinity: " << numeric_limits<int>::has_infinity << endl;
  return 0;
}
GMan
Awww yea, I knew there would be one :). Thank you!
Jesse Emond
+1 for the boolalpha alone!
Assaf Lavie
+4  A: 

(related to C, but I think this also applies for C++)

You can also try "enquire", which is a script which can re-create limits.h for your compiler. A quote from the projetc's home page:

This is a program that determines many properties of the C compiler and machine that it is run on, such as minimum and maximum [un]signed char/int/long, many properties of float/ [long] double, and so on.

As an option it produces the ANSI C float.h and limits.h files.

As a further option, it even checks that the compiler reads the header files correctly.

It is a good test-case for compilers, since it exercises them with many limiting values, such as the minimum and maximum floating-point numbers.

elcuco
+2  A: 
#include <limits>

std::numeric_limits<type>::max() // min() etc
rmn
+7  A: 

I see that the 'correct' answer has already been given: Use <limits> and let the magic happen. I happen to find that answer unsatisfying, since the question is:

would it be really hard to write a method to calculate the limit of a variable type?

The answer is : easy for integer types, hard for float types. There are 3 basic types of algorithms you would need to do this. signed, unsigned, and floating point. each has a different algorithm for how you get the min and max, and the actual code involves some bit twiddling, and in the case of floating point, you have to loop unless you have a known integer type that is the same size as the float type.

So, here it is.

Unsigned is easy. the min is when all bits are 0's, the max is when all bits are 1's.

const unsigned type unsigned_type_min = (unsigned type)0;    
const unsigned type unsigned_type_max = ~(unsigned type)0;

For signed, the min is when the sign bit is set but all of the other bits are zeros, the max is when all bits except the sign bit are set. with out knowing the size of the type, we don't know where the sign bit is, but we can use some bit tricks to get this to work.

const signed type signed_type_max = (signed type)(unsigned_type_max >> 1);
const signed type signed_type_min = (signed type)(~(signed_type_max));

for floating point, there are 4 limits, although knowning only the positive limits is sufficient, the negative limits are just sign inverted positive limits. There a potentially many ways to represent floating point numbers, but for those that use binary (rather than base 10) floating point, nearly everyone uses IEEE representations.

For IEEE floats, The smallest positive floating point value is when the low bit of the exponent is 1 and all other bits are 0's. The largest negative floating point value is the bitwise inverse of this. However, without an integer type that is known to be the same size as the given floating point type, there isn't any way to do this bit manipulation other than executing a loop. if you have an integer type that you know is the same size as your floating point type, you can do this as a single operation.

const float_type get_float_type_smallest() {
   const float_type float_1 = (float_type)1.0;
   const float_type float_2 = (float_type)0.5;
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ((byte*)&float_1)[ii] ^ ((byte*)&float_2)[ii];
   return u.fl;
   }

const float_type get_float_type_largest() {
   union {
      byte ab[sizeof(float_type)];
      float_type fl;
      } u;
   u.fl = get_float_type_smallest();
   for (int ii = 0; ii < 0; ++ii)
      u.ab[ii] = ~u.ab[ii];
   return -u.fl; // Need to re-invert the sign bit.
   }
John Knoeller
I think your answer is the most informative, so here's an upvote and my regards!
S.C. Madsen
GMan