第2.15章: limits
什么是 limits?
C++ 中每个数值类型都有一个它能表示的取值范围。
例如 int 的最小值与最大值依平台而定。
头文件 <limits> 提供了模板 std::numeric_limits<T>,
让你可以在编译期查询这些属性。
完整细节请见权威参考: cppreference:std::numeric_limits
sizeof(T) 与 numeric_limits<T>
我们已经知道 sizeof(T) 告诉我们一个类型占多少字节。
但 std::numeric_limits<T> 更进一步:它告诉我们该类型能表示多少位精度。
std::numeric_limits<T>::digits—— 精度的二进制位数。std::numeric_limits<T>::digits10—— 可以无变化表示的十进制位数。std::numeric_limits<T>::max_digits10—— 唯一表示所有值所需的最大十进制位数。
#include <limits>
#include <cstddef>
#include <fast_io.h>
int main() {
using namespace ::fast_io::iomnp;
println("sizeof(double) = ", sizeof(double), " bytes\n"
"digits (binary) = ", ::std::numeric_limits<double>::digits, "\n"
"digits10 (decimal) = ", ::std::numeric_limits<double>::digits10, "\n"
"max_digits10 (decimal) = ", ::std::numeric_limits<double>::max_digits10);
}
例如,double 通常是 8 字节(64 位)。
但其中只有 53 位用于精度(digits),
这大约对应 15–17 位十进制数字(digits10 与 max_digits10)。
基本的范围示例
#include <limits>
#include <cstddef>
#include <fast_io.h>
int main() {
using namespace ::fast_io::iomnp;
println("::std::size_t max = ", ::std::numeric_limits<::std::size_t>::max(), "\n"
"::std::size_t min = ", ::std::numeric_limits<::std::size_t>::min());
}
std::numeric_limits<T>::max() 给出类型 T 能表示的最大值。
std::numeric_limits<T>::min() 给出能表示的最小值。
对 ::std::size_t 这类无符号类型,min() 始终是 0。
其他有用的属性
std::numeric_limits<T>::lowest()—— 最低的有限值(用于浮点类型)。std::numeric_limits<T>::epsilon()—— 1 与下一个可表示值之间的差(用于浮点类型)。std::numeric_limits<T>::infinity()—— 若支持,表示正无穷。std::numeric_limits<T>::is_signed—— 说明该类型是否有符号。
为什么上限很重要
了解一个类型的范围有助于防止溢出与下溢错误。
例如,对 std::numeric_limits<int>::max() 加 1 会导致溢出。
对浮点类型而言,理解 digits、digits10 和 epsilon
对于数值稳定性与精度至关重要。
要点
sizeof(T)给出一个类型占用的字节数。std::numeric_limits<T>::digits给出精度的二进制位数。digits10与max_digits10描述十进制精度。max()与min()给出类型的取值范围。- 浮点类型还提供
lowest、epsilon和infinity等额外属性。 - 理解上限有助于避免溢出、下溢与精度错误。
- 完整细节见 cppreference:std::numeric_limits 。