C++数值计算:从基础到应用
立即解锁
发布时间: 2025-08-22 00:56:40 阅读量: 2 订阅数: 8 


C++编程语言精髓与实践
# C++ 数值计算:从基础到应用
## 1. 引言
C++ 虽并非专为数值计算设计,但数值计算常与数据库访问、网络、仪器控制、图形、模拟和金融分析等工作结合,使 C++ 成为大型系统中数值计算的理想选择。如今,数值方法不再局限于简单的浮点向量循环,当计算需要更复杂的数据结构时,C++ 的优势便凸显出来。
## 2. 数值限制
### 2.1 数值限制模板
要处理数字,我们需了解内置数值类型的一般属性,这些属性由实现定义。`<limits>` 中的 `numeric_limits` 模板特化提供了相关信息。例如:
```cpp
void f(double d, int i)
{
char classification[numeric_limits<unsigned char>::max()];
if (numeric_limits<unsigned char>::digits==numeric_limits<char>::digits ) {
// chars are unsigned
}
if (i<numeric_limits<short>::min() || numeric_limits<short>::max()<i) {
// i cannot be stored in a short without loss of digits
}
if (0<d && d<numeric_limits<double>::epsilon()) d = 0;
if (numeric_limits<Quad>::is_specialized) {
// limits information is available for type Quad
}
}
```
该模板为每个基本数值类型(字符类型、整数类型、浮点类型和 `bool`)提供特化,但不包括 `void`、枚举或库类型(如 `complex<double>`)。
### 2.2 整数类型示例
以 `char` 为例,若 `char` 为 8 位有符号类型,其 `numeric_limits<char>` 特化如下:
```cpp
template<>
class numeric_limits<char> {
public:
static const bool is_specialized = true;
static const int digits = 7;
static const bool is_signed = true;
static const bool is_integer = true;
static constexpr char min() noexcept { return -128; }
static constexpr char max() noexcept { return 127; }
// lots of declarations not relevant to a char
};
```
这些函数为 `constexpr`,可在常量表达式中使用,且无运行时开销。
### 2.3 浮点类型示例
对于 `float`,其 `numeric_limits<float>` 特化如下:
```cpp
template<>
class numeric_limits<float> {
public:
static const bool is_specialized = true;
static const int radix = 2;
static const int digits = 24;
static const int digits10 = 9;
static const bool is_signed = true;
static const bool is_integer = false;
static const bool is_exact = false;
static constexpr float min() noexcept { return 1.17549435E-38F; }
static constexpr float max() noexcept { return 3.40282347E+38F; }
static constexpr float lowest() noexcept { return -3.40282347E+38F; }
static constexpr float epsilon() noexcept { return 1.19209290E-07F; }
static constexpr float round_error() noexcept { return 0.5F; }
static constexpr float infinity() noexcept { return /* some value */; }
static constexpr float quiet_NaN() noexcept { return /* some value */; }
static constexpr float signaling_NaN() noexcept { return /* some value */; }
static constexpr float denorm_min() noexcept { return min(); }
static const int min_exponent = -125;
static const int min_exponent10 = -37;
static const int max_exponent = +128;
static const int max_exponent10 = +38;
static const bool has_infinity = true;
static const bool has_quiet_NaN = true;
static const bool has_signaling_NaN = true;
static const float_denorm_style has_denorm = denorm_absent;
static const bool has_denorm_loss = false;
static const bool is_iec559 = true;
static const bool is_bounded = true;
static const bool is_modulo = false;
static const bool traps = true;
static const bool tinyness_before = true;
static const float_round_style round_style = round_to_nearest;
};
```
其中,`min()` 是最小的正规范化数,`epsilon` 是使 `1+epsilon−1` 大于 0 的最小正浮点数。
### 2.4 自定义类型的数值限制
定义自定义标量类型时,最好提供相应的 `numeric_limits` 特化。若使用非数值类型,`numeric_limits` 主模板的 `is_specialized` 为 `false`,表示无可用信息。
### 2.5 限制宏
C++ 从 C 继承了描述整数和浮点类型属性的宏。整数限制宏在 `<climits>` 中,浮点限制宏在 `<cfloat>` 和 `<float.h>` 中。如下表所示:
| 宏名称 | 描述 |
| ---- | ---- |
| `CHAR_BIT` | char 的位数(通常为 8) |
| `CHAR_MIN` | char 的最小值(可能为负) |
| `CHAR_MAX` | char 的最大值(有符号时通常为 127,无符号时为 255) |
| `INT_MIN` | int 的最小值 |
| `LONG_MAX` | long 的最大值 |
| `FLT_MIN` | 最小正 float 值 |
| `FLT_MAX` | float 的最大值 |
| `FLT_DIG` | float 的十进制精度位数 |
| `FLT_MAX_10_EXP` | float 的最大十进制指数 |
| `DBL_MIN` | double 的最小值 |
| `DBL_MAX` | double 的最大值 |
| `DBL_EPSILON` | 使 `1.0+DBL_EPSILON!=1.0` 的最小 double 值 |
## 3. 标准数学函数
`<cmath>` 中包含常见的标准数学函数,如绝对值、向上取整、向下取整、平方根、三角函数、双曲函数、指数函数和对数函数等。这些函数有接受 `float`、`double`、`long double` 和 `complex` 参数的版本,返回类型与参数类型相同。错误通过设置 `<cerrno>` 中的 `errno` 来报告,`EDOM` 表示定义域错误,`ERANGE` 表示范围错误。示例如下:
```cpp
void f()
{
errno = 0; // clear old error state
sqrt(-1);
if (errno==EDOM) cerr << "sqrt() not defined for negative argument";
pow(numeric_limits<double>::max(),2);
if (errno == ERANGE) cerr << "result of pow() too large to represent as a double";
}
```
此外,`<cstdlib>` 中还有一些数学函数,如绝对值和除法函数。还有一个单独的 ISO 标准定义了特殊数学函数,实现可将其添加到 `<cmath>` 中。
## 4. 复数
标准库提供了 `complex<float>`、`complex<double>` 和 `complex<long double>` 复数类型。`complex<Scalar>` 中 `Scalar` 支持常见算术运算,但不一定具有可移植性。
```cpp
template<typename Scalar>
class complex {
Scalar re, im;
public:
complex(const Scalar & r = Scalar{}, const Scalar & i = Scalar{}) :re(r), im(i) { }
Scalar real() const { return re; }
void real(Scalar r) { re=r; }
Scalar imag() const { return im; }
void imag(Scalar i) { im = i; }
template<typename X>
complex(const complex<X>&);
complex<T>& operator=(const T&);
complex& operator=(const complex&);
```
0
0
复制全文
相关推荐










