C++中的数值限制与类型特性
立即解锁
发布时间: 2025-08-22 00:43:47 阅读量: 2 订阅数: 16 


深入解析C++标准库:从入门到精通
### C++ 中的数值限制与类型特性
#### 1. 数值限制
数值类型通常具有依赖于平台的限制。C++ 标准库在模板 `numeric_limits` 中提供了这些限制,它取代并补充了普通的预处理器 C 常量。这些常量在 `<climits>` 和 `<limits.h>` 中用于整数类型,在 `<cfloat>` 和 `<float.h>` 中用于浮点类型。新的数值限制概念有两个优点:一是提供了更高的类型安全性;二是使程序员能够编写评估这些限制的模板。
以下是一些内置类型的最小大小:
| Type | Minimum Size |
| ---- | ---- |
| char | 1 byte (8 bits) |
| short int | 2 bytes |
| int | 2 bytes |
| long int | 4 bytes |
| long long int | 8 bytes |
| float | 4 bytes |
| double | 8 bytes |
| long double | 8 bytes |
##### 1.1 `numeric_limits` 类模板
- **通用模板**:为任何类型提供默认的数值。
```cpp
namespace std {
// general numeric limits as default for any type
template <typename T>
class numeric_limits {
public:
// by default no specialization for any type T exists
static constexpr bool is_specialized = false;
// other members are meaningless for the general template
};
}
```
这个通用模板表示对于类型 T 没有可用的数值限制,通过将成员 `is_specialized` 设置为 `false` 来实现。
- **模板特化**:为每个数值类型定义数值限制。
```cpp
namespace std {
// numeric limits for int
// - implementation defined
template<> class numeric_limits<int> {
public:
// yes, a specialization for numeric limits of int does exist
static constexpr bool is_specialized = true;
static constexpr int min() noexcept {
return -2147483648;
}
static constexpr int max() noexcept {
return 2147483647;
}
static constexpr int digits = 31;
};
}
```
这里,`is_specialized` 被设置为 `true`,其他成员具有特定类型的数值限制值。
通用的 `numeric_limits` 模板及其标准特化在头文件 `<limits>` 中提供。特化适用于任何可以表示数值的基本类型,并且可以轻松地为用户定义的数值类型进行补充。
以下是 `numeric_limits` 类的一些成员及其含义:
| Member | Meaning | C Constants |
| ---- | ---- | ---- |
| is_specialized | Type has specialization for numeric limits | |
| is_signed | Type is signed | |
| is_integer | Type is integer | |
| is_exact | Calculations produce no rounding errors (true for all integer types) | |
| is_bounded | The set of values representable is finite (true for all built-in types) | |
| is_modulo | Adding two positive numbers may wrap to a lesser result | |
| is_iec559 | Conforms to standards IEC 559 and IEEE 754 | |
| min() | Minimum finite value (minimum positive normalized value for floating-point types with denormalization; meaningful if is_bounded||!is_signed) | INT_MIN,FLT_MIN,CHAR_MIN,... |
| max() | Maximum finite value (meaningful if is_bounded) | INT_MAX,FLT_MAX,... |
| lowest() | Maximum negative finite value (meaningful if is_bounded; since C++11) | |
| digits | Character/integer: number of bits, excluding sign (binary digits); Floating point: number of radix digits in the mantissa | CHAR_BIT,FLT_MANT_DIG,... |
| digits10 | Number of decimal digits (meaningful if is_bounded) | FLT_DIG,... |
| max_digits10 | Number of required decimal digits to ensure that values that differ are always differentiated (meaningful for all floating-point types; since C++11) | |
| radix | Integer: base of the representation (almost always 2); Floating point: base of the exponent representation | FLT_RADIX |
| min_exponent | Minimum negative integer exponent for base radix | FLT_MIN_EXP,... |
| max_exponent | Maximum positive integer exponent for base radix | FLT_MAX_EXP,... |
| min_exponent10 | Minimum negative integer exponent for base 10 | FLT_MIN_10_EXP,... |
| max_exponent10 | Maximum positive integer exponent for base 10 | FLT_MAX_10_EXP,... |
| epsilon() | Difference of 1 and least value greater than 1 | FLT_EPSILON,... |
| round_style | Rounding style | |
| round_error() | Measure of the maximum rounding error (according to standard ISO/IEC 10967 - 1) | |
| has_infinity | Type has representation for positive infinity | |
| infinity() | Representation of positive infinity, if available | |
| has_quiet_NaN | Type has representation for nonsignaling “Not a Number” | |
| quiet_NaN() | Representation of quiet “Not a Number,” if available | |
以下是 `float` 类型的完整特化示例:
```cpp
namespace std {
template<> class numeric_limits<float> {
public:
// yes, a specialization for numeric limits of float does exist
static constexpr bool is_specialized = true;
inline constexpr float min() noexcept {
return 1.17549435E-38F;
}
inline constexpr float max() noexcept {
return 3.40282347E+38F;
}
inline constexpr float lowest() noexcept {
return -3.40282347E+38F;
}
static constexpr int digits = 24;
static constexpr int digits10 = 6;
static constexpr int max_digits10 = 9;
static constexpr bool is_signed = true;
static constexpr bool is_integer = false;
static constexpr bool is_exact = false;
static constexpr bool is_bounded = true;
static constexpr bool is_modulo = false;
static constexpr bool is_iec559 = true;
static constexpr int radix = 2;
inline constexpr float epsilon() noexcept {
return 1.19209290E-07F;
}
static constexpr float_round_style round_style = round_to_nearest;
```
0
0
复制全文