3

Is there a simple, clean way of determining at compile time the max and min values for a variable of some (otherwise unknown at the moment) integer variable or type? Using templates?

For example:

// Somewhere in a large project is:
typedef unsigned long XType;
typedef char YType;
// ...

// Somewhere else
   XType a;
   YType b;
   LONGLONG c,d,e,f;
   c = MinOfType(a); // Same as c = 0;
   d = MaxOfType(a); // Same as d = 0xffffffff;
   e = MinOfType(b); // Same as e = -128;
   f = MaxOfType(b); // Same as f = 127;
// Also would be nice
   e = MinOfType(YType); // Same as e = -128; // Using the typename directly
// Or perhaps
   e = MinOfType<YType>(); // Same as e = -128; // Using the typename directly
Harvey
  • 2,062
  • 2
  • 21
  • 38
  • The value of a variable can't be known at compile time, but constants can. – Steve Guidi Dec 14 '09 at 15:34
  • The "value" of the variable is not needed in the above code. But is not the type of a variable, as in my example, known at compile time. These variables are not polymorphic classes, just one of the basic integer types. Or am I missing something (very possible). I think I have the numeric_limits working for case where the typename is used directly. Now can I do something like: e=numeric_limits::max(); ? – Harvey Dec 14 '09 at 22:46
  • Surely the type "a" or "b" is known by the compiler, at compile time. Otherwise the compiler would not be able to generate code using these variables at all. – Harvey Dec 14 '09 at 22:56

5 Answers5

14

Use std::numeric_limits, it is there for exactly this type of requirement. You can take a look at this example for the usage.

Naveen
  • 74,600
  • 47
  • 176
  • 233
  • 5
    AFAIK, those are not *compile-time*, though (if OP himself realizes what exactly he wants). – UncleBens Dec 14 '09 at 15:28
  • 1
    Not compile-time, but fairly close to it if optimisations are enabled. – Raphaël Saint-Pierre Dec 14 '09 at 15:33
  • 5
    RaphaelSP: if compile-time is actually required, such as for a template parameter or enumerator, then it doesn't matter what optimizations are enabled---either the expression is or it isn't. Compare to constexprs in C++0x. –  Dec 14 '09 at 15:41
  • 1
    Good point. I just translated "compile-time" to "fast" (given the code snippet does not do sensible use of the "compile-time" bit). – Raphaël Saint-Pierre Dec 14 '09 at 16:09
9

Check out boost integer_traits.

moonshadow
  • 86,889
  • 7
  • 82
  • 122
3

See this question maximum value of int - you can also use "min" in the places where the answers used "max"

Community
  • 1
  • 1
0

If you have access to c++11, you can use a combination of decltype and std::numeric_limits. Rewriting your sample code would look like this:

#include <limits>

typedef unsigned long XType;
typedef char YType;

XType a;
YType b;
LONGLONG c,d,e,f;
c = std::numeric_limits< decltype(a) >::min(); // Same as c = 0;
d = std::numeric_limits< decltype(a) >::max(); // Same as d = 0xffffffff;
e = std::numeric_limits< decltype(b) >::min(); // Same as e = -128;
f = std::numeric_limits< decltype(b) >::max(); // Same as f = 127;
e = std::numeric_limits< YType >::min(); // Same as e = -128; // Using the typename directly

decltype will pull the type from an expression, snagging the variable type in this case, and let you use it in other places that expect a type such as a template. And it all happens at compile time such that you could assign it to a constexpr.

constexpr decltype(a) g = std::numeric_limits< decltype(a) >::min();

Here g would be of the same type as a, would have the value 0, and all be determined at compile time.

kalaxy
  • 1,608
  • 1
  • 14
  • 14
0

Include header <limits> to reach template class std::numeric_limits. The numeric type of your variable is used to find a specialization of that template class that will provide the maximum value via function max() and the minimum value via min(), in addition to several other facets of the type.

Note that the interpretation for minimum is different for integral and floating point types. For the former, it's the most negative value for a signed type, and zero for an unsigned type, but for the latter, it's the smallest representable value, which is very close to zero.

seh
  • 14,999
  • 2
  • 48
  • 58
  • Wrong. It is not compile time. – Alexey Malistov Dec 14 '09 at 16:51
  • True, and the client code above could not distinguish evaluation at run time from compile time. All the implementations for `numeric_limits` I've seen are functions exposing constants defined at compile-time, but I don't think it was a mistake that the standard mandates those values be exposed through functions as opposed to constant member values -- in particular, to accommodate the floating point types or some other non-ICE. – seh Dec 14 '09 at 17:35