Show Lecture.Limits as a slide show.
CS253 Limits
C integer types
<limits.h>, alias <climits>
C floating-point types
<float.h>, alias <cfloat>
Pop Quiz
Quick, now:
- What symbol says how many decimal digits are in the mantissa of a
long double?
- What symbol gives the maximum value of a short?
- What symbol gives the maximum value of a size_t?
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();
constexpr int largest = numeric_limits<char>::max();
cout << "A plain char value ranges from "
<< smallest << " to " << largest << ".\n";
A plain char value ranges from -128 to 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
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>::is_signed << '\n'
<< numeric_limits<size_t>::is_integer << '\n'
<< numeric_limits<size_t>::min() << '\n'
<< numeric_limits<size_t>::max() << '\n';
false
true
64
19
false
true
0
18446744073709551615
boolalpha 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.
- Remember that 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.