Show Lecture.Limits as a slide show.
CS253 Limits
Inclusion
To do numeric_limits, you need to:
#include <limits>
Rare uses of the old C limits #defines requires:
#include <climits>
#include <cfloat>
Also, CHAR_BIT is how many bits in a char.
Pop Quiz
Quick, now:
What symbol says how many decimal digits are in the mantissa of a long double?
LDBL_DIG
What symbol gives the maximum value of a short?
SHRT_MAX
What symbol gives the maximum value of a size_t?
There isn’t one. It’s probably ULLONG_MAX, because size_t is often an
alias for unsigned long long, but it doesn’t have to be.
C++ way
- <limits> defines the template class numeric_limits,
which is specialized for all built-in types.
- It has many
static constexpr
methods and constants, including:
.min()
.max()
.digits
number of bits, excluding sign/exponent
.digits10
number of decimal digits, excluding sign/exponent
.min_exponent10
.max_exponent10
- Why are
.min()
& .max()
methods, not variables like
.digits
?
Simple Example
What is the range of values for a char?
constexpr int smallest = numeric_limits<char>::min(),
largest = numeric_limits<char>::max();
cout << "Plain char: " << smallest << "…" << largest;
Plain char: -128…127
- Look—negative characters! At least, on this computer.
A char can be signed or unsigned.
- Sure, on today’s computers, a char is almost
always eight bits, but not always.
- Guessing is a poor way to know—use numeric_limits!
Integer Example
cout << numeric_limits<int>::digits10 << '\n'
<< numeric_limits<int>::min() << '\n'
<< numeric_limits<int>::max() << '\n';
9
-2147483648
2147483647
- We use
::
to we call a static method.
We don’t need an instance for that.
- We’d use
.
if we had an instance of this class.
digits10
is a constant, not a method,
so it’s digits10
, not digits10()
.
Floating-Point Examples
using fl = numeric_limits<float>; // a type alias
cout << fl::digits << '\n'
<< fl::digits10 << '\n'
<< fl::min_exponent << '\n'
<< fl::max_exponent << '\n'
<< fl::epsilon() << '\n'
<< fl::lowest() << '\n'
<< fl::min() << '\n'
<< fl::max() << '\n';
24
6
-125
128
1.19209e-07
-3.40282e+38
1.17549e-38
3.40282e+38
constexpr numeric_limits<long double> ld; // an instance
cout << ld.digits << '\n'
<< ld.digits10 << '\n'
<< ld.min_exponent << '\n'
<< ld.max_exponent << '\n'
<< ld.epsilon() << '\n'
<< ld.lowest() << '\n'
<< ld.min() << '\n'
<< ld.max() << '\n';
64
18
-16381
16384
1.0842e-19
-1.18973e+4932
3.3621e-4932
1.18973e+4932
Aliases work, too
size_t is an alias for an unsigned integer type. Which one? We
don’t care. Since size_t is an alias for another type, it works with
numeric_limits:
cout << boolalpha
<< numeric_limits<size_t>::is_signed << '\n'
<< numeric_limits<size_t>::is_integer << '\n'
<< numeric_limits<size_t>::digits << '\n'
<< numeric_limits<size_t>::digits10 << '\n'
<< numeric_limits<size_t>::min() << '\n'
<< numeric_limits<size_t>::max() << '\n';
false
true
64
19
0
18446744073709551615
boolalpha is an I/O manipulator. It says to display bool values
as false and true, not 0
and 1
.
Types
cout << numeric_limits<long>::max() << '\n'
<< numeric_limits<int>::max() << '\n'
<< numeric_limits<short>::max() << '\n'
<< numeric_limits<char>::max() << '\n';
9223372036854775807
2147483647
32767
␡
- That last line sure is disappointing—I expected 127 or 255.
- The result type of
::max()
and ::min()
is the same type as
you’re asking about.
- Therefore, the first line of output is a value of type long.
- Similarly, the last line is a char. When we write a char,
we don’t get a numeric value; we get a character:
- See a few slides back, where we put the result of
::max()
into an int.
A Mystery
Holmes & Watson in Zurich
cout << numeric_limits<size_t>::min << '\n'
<< numeric_limits<size_t>::min() << '\n';
1
0
Why did that compile? One line must be wrong!
- The smallest value for size_t, an unsigned type, is
0
.
The second line is correct: .min()
is a function.
- How does the first line compile?
- A function name is a pointer to the function, just like an array name
is a pointer to its first element.
- A pointer-to-method can’t be displayed with
<<
; but bool can.
- A built-in conversion from any pointer to bool exists.
- The pointer is non-null, so converts to true,
which displays as
1
, without boolalpha.