13.32 <limits>
The <limits> header declares the
numeric_limits class template and related types
and specializations that define the limits and characteristics of the
fundamental arithmetic types (such as the largest possible
int). It is the C++ equivalent of the C headers
<cfloat> and
<climits> (and the
wchar_t limits in
<cwchar>).
The <limits> header has a number of
advantages over the <cfloat> and
<climits> declarations. In particular, by
using a template, you can write your own template-based classes that
depend on the characteristics of a template parameter; this is not
possible with the macro-based C headers.
float_denorm_style type |
Represents existence of denormalized, floating-point values
|
enum float_denorm_style {
denorm_indeterminate = -1;
denorm_absent = 0;
denorm_present = 1;
};
|
|
The float_denorm_style type is an enumerated type
that represents whether denormalized floating-point values are
supported.
float_round_style type |
Represents the floating-point rounding style
|
enum float_round_style {
round_indeterminate = -1,
round_toward_zero = 0,
round_to_nearest = 1,
round_toward_infinity = 2,
round_toward_neg_infinity = 3
};
|
|
The float_round_style type is an enumerated type
that represents how floating-point numbers are rounded.
numeric_limits class template |
Represents the limits and characteristics of an arithmetic type
|
template<typename T>
class numeric_limits{
public:
static const bool is_specialized = false;
static T min( ) throw( );
static T max( ) throw( );
static const int digits = 0;
static const int digits10 = 0;
static const bool is_signed = false;
static const bool is_integer = false;
static const bool is_exact = false;
static const int radix = 0;
static T epsilon( ) throw( );
static T round_error( ) throw( );
static const int min_exponent = 0;
static const int min_exponent10 = 0;
static const int max_exponent = 0;
static const int max_exponent10 = 0;
static const bool has_infinity = false;
static const bool has_quiet_NaN = false;
static const bool has_signaling_NaN = false;
static const float_denorm_style has_denorm = denorm_absent;
static const bool has_denorm_loss = false;
static T infinity( ) throw( );
static T quiet_NaN( ) throw( );
static T signaling_NaN( ) throw( );
static T denorm_min( ) throw( );
static const bool is_iec559 = false;
static const bool is_bounded = false;
static const bool is_modulo = false;
static const bool traps = false;
static const bool tinyness_before = false;
static const float_round_style round_style = round_toward_zero;
};
|
|
The numeric_limits class template represents the
limits and characteristics of an arithmetic type. The data members
that are shown as static const
are constants that you can use in other integral constant
expressions.
The default is for all members to be 0 or
false. The header has specializations for all
fundamental types, and only for the fundamental types. Every
specialization in the standard library defines every member, even if
the member does not pertain to the type (e.g., floating-point
characteristics of an integral type). Meaningless members are defined
as 0 or false.
You can specialize numeric_limits for your own
types. For example, suppose you write a class,
bigint, to represent integers of arbitrary size.
You can define your specialization to show that the type is
unbounded, signed, integral, etc. You should follow the convention of
the standard library, namely, by defining all members, even if they
do not apply to your type. Be sure to define
is_specialized as true.
Use numeric_limits to query the properties or
traits of a numeric type. For example, suppose you are writing a data
analysis program. Among the data are points you want to ignore, but
you need to keep their places in the data array. You decide to insert
a special marker value. Ideally, the marker value (such as infinity)
cannot possibly appear in the actual data stream. If the
floating-point type that you are using does not support infinity, you
can use the maximum finite value. Example 13-23 lists
the no_data function, which returns the value used
for the no-data marker.
Example
Example 13-23. Using infinity or maximum finite value to mean "no data"
// Define a template that will differentiate types that have a specialized
// numeric_limits and an explicit value for infinity.
template<typename T, bool is_specialized, bool has_infinity>
struct max_or_infinity
{};
// Specialize the template to obtain the value of infinity.
template<typename T>
struct max_or_infinity<T, true, true>
{
static T value( )
{ return std::numeric_limits<T>::infinity( ); }
};
// Specialize the template if infinity is not supported.
template<typename T>
struct max_or_infinity<T, true, false>
{
static T value( ) { return std::numeric_limits<T>::max( ); }
};
// Note that a type without a numeric_limits specialization does not have a
// max_or_infinity specialization, so the no_data function would result in
// compile-time errors when applied to such a type.
//
// The no_data function returns a value that can be used to mark points that do
// not have valid data.
template<typename T>
T no_data( )
{
return max_or_infinity<T,
std::numeric_limits<T>::is_specialized,
std::numeric_limits<T>::has_infinity>::value( );
}
The C++ standard mandates that all integers are binary and use
two's complement, ones' complement,
or signed magnitude representation. The representation of
floating-point numbers is not specified. The
numeric_limits template assumes that a number is
represented as a sign, a significand (sometimes called the
mantissa), a base, and an exponent:
- x = sign x significand x base exponent
In everyday arithmetic, we are used to working with a
base of 10. (The base is also called the
radix.) The most common bases for computer
arithmetic, however, are 16 and 2. Many modern workstations use the
IEC 60559 (IEEE 754) standard for floating-point arithmetic, which
uses a base of 2.
The significand is a string of digits in the
given base. There is an implied radix point at the start of the
significand, so the value of the significand is always less than one.
(A radix point is the
generalization of a decimal point for any radix.)
A finite floating-point value is normalized if
the first digit of its significand is nonzero, or if the entire value
is 0. The term denormalized
means a finite value is not normalized.
The precision of a floating-point type is the
maximum number of places in the significand. The
range of a floating-point type depends primarily
on the minimum and maximum values for the exponent.
The following are descriptions of the members of
numeric_limits:
- static T denorm_min( ) throw( )
-
Returns the smallest positive, denormalized floating-point value. If
has_denorm is false, it returns
the smallest positive normalized value. For non-floating-point types,
it returns 0.
- static const int digits
-
The number of radix digits that can be
represented. For integer types, it is the number of non-sign bits;
for floating-point types, it is the number of places in the
significand.
- static const int digits10
-
The number of decimal digits that can be represented. If
is_bounded is false,
digits10 is 0.
- static T epsilon( ) throw( )
-
Returns the difference between 1.0 and the smallest representable
value greater than 1.0. For integral types,
epsilon returns 0.
- static const float_denorm_style has_denorm
-
Indicates the denormalized, floating-point style. It is
denorm_indeterminate if the style cannot be
determined at compile time. It is meaningful for all floating-point
types.
- static const bool has_denorm_loss
-
Indicates whether the loss of accuracy in a floating-point
computation is a denormalization loss rather than an inexact result.
- static const bool has_infinity
-
Indicates whether the floating-point type can represent positive
infinity. In particular, has_infinity is
true when is_iec559 is
true.
- static const bool has_quiet_NaN
-
Indicates whether the floating-point type can represent a quiet
(nonsignaling) NaN (not-a-number). In particular, this is
true when is_iec559 is
true.
- static const bool has_signaling_NaN
-
Indicates whether the floating point type can represent a signaling
NaN. In particular, this is true when
is_iec559 is true.
- static T infinity( ) throw( )
-
Returns the value of positive infinity if
has_infinity is true.
- static const bool is_bounded
-
Indicates whether the type represents a finite set of values. This is
true for all fundamental types.
- static const bool is_exact
-
Indicates whether the type represents values exactly. It is
true for all integral types and
false for the fundamental floating-point types.
- static const bool is_iec559
-
Indicates whether the type follows the IEC 60559 (IEEE 754) standard
for floating-point arithmetic. It is meaningful only for
floating-point types. Among the requirements of the IEC 60559
standard are support for positive and negative infinity, and for
values that are NaN.
- static const bool is_integer
-
true for all integral types.
- static const bool is_modulo
-
Indicates whether the type uses modulo arithmetic. This is always
true for unsigned integral types and often
true for signed integral types. It is
false for typical floating-point types.
- static const bool is_signed
-
Indicates whether the type is signed, that is, supports positive and
negative values.
- static const bool is_specialized
-
Indicates whether numeric_limits is specialized
for the type. It is false by default, so you can
detect whether numeric_limits<> has been
specialized for a particular type, and therefore determine whether a
false or 0 value is meaningful.
- static T max( ) throw( )
-
Returns the maximum finite value when is_bounded
is true.
- static const int max_exponent
-
The largest allowable exponent for a finite floating-point number.
- static const int max_exponent10
-
The largest allowable decimal exponent for a finite floating-point
number.
- static T min( ) throw( )
-
Returns the minimum finite value. It is meaningful when
is_bounded is true or when
is_bounded and is_signed are
both false.
- static const int min_exponent
-
The smallest allowable exponent for a floating-point number such that
radix raised to min_exponent
- 1 is representable as a
normalized floating-point number.
- static const int min_exponent10
-
The smallest negative decimal exponent such that 10 raised to
min_exponent10 is representable as a normalized
floating-point number.
- static T quiet_NaN( ) throw( )
-
Returns a quiet NaN value if has_quiet_NaN is
true.
- static const int radix
-
The base used in the representation of a numeric value. For
floating-point numbers, it is the base of the exponent.
- static T round_error( ) throw( )
-
Returns the maximum rounding error.
- static const float_round_style round_style
-
Indicates the rounding style used by the floating-point type. (See
the float_round_style type for a definition of the
possible return values.) For integral types, the return value is
always round_toward_zero.
- static T signaling_NaN( ) throw( )
-
Returns a signaling NaN value if has_signaling_NaN
is true.
- static const bool tinyness_before
-
Indicates whether a floating-point type tests for denormalized values
before rounding.
- static const bool traps
-
Indicates whether arithmetic errors trap, that
is, result in signals or exceptions. It is false
if errors are quietly ignored.
The numeric_limits template is specialized for all
the fundamental numeric types and for no other types in the C++
standard. In each case, is_specialized is
true, and other members are set as appropriate.
The C++ standard (by way of the C standard) defines the minimum
requirements for an implementation. The requirements for integral
types are given in <climits>, and for
floating-point types in <cfloat>.
The following are the standard specializations:
- numeric_limits<bool>
- numeric_limits<char>
- numeric_limits<double>
- numeric_limits<float>
- numeric_limits<int>
- numeric_limits<long>
- numeric_limits<long double>
- numeric_limits<short>
- numeric_limits<signed char>
- numeric_limits<unsigned char>
- numeric_limits<unsigned int>
- numeric_limits<unsigned long>
- numeric_limits<unsigned short>
- numeric_limits<wchar_t>
|