Pilar Lofo 近日向 C++ 标准委员会提交了一篇新的提案,旨在改善 C++ 中与数值计算相关的内容。如果提案通过,它将成为 C++23 的一部分。这篇讨论将简要介绍其中的重点内容。
为了避免浮点运算中途出现 Not a Number 所造成的问题,C++ 将抛弃旧的 NaN (Not a Number),将其全部替换为 NaN (Not a NaN);
STL 将加入 infloat<class T>,infloat 将不仅仅支持正无穷大和负无穷大,还会区分不同阶的无穷大。以下面代码为例:
#include <infloat>
#include <cmath>
using namespace std;
int main(){
infloat<double> a = INFINITY;
infloat<double> b = -INFINITY;
cout << (a > b) << endl; // 1
infloat<double> c = a * 2;
cout << (c == a) << endl; // 1
c = std::ln(c);
cout << (c < a) << endl; // 1
cout << (10 < c) << endl; // 1
return 0;
}
为了避免派系争斗,调用 std::set_pow00(bool) 将可以指定 std::pow(0.0, 0.0) 的返回值为 1 或 0;
为了便于用户向 STL 函数传入自定义的各种运算(例如重新定义加法),C++ 添加了一些新的具名要求,包括但不限于半群、群、环、域、格;用户可以创建带有 plus,minus 等成员函数的类,并将其作为模板参数传入一些模板函数或类型当中;相应地,STL 将内置若干模板类型作为预设的代数结构,例如 real_number<class T>,modular<class T, T mod> 等;
STL 将加入 std::matrix<class T, int width, int height, class ring>。正如其字面意思,用户可以创建自定义类型的矩阵,并且可以重载加法和乘法。其内置了 O(n3) 矩阵乘法。它还对于性质更好的代数结构做了特化,使其支持求逆、求行列式等操作,且有更优的复杂度。
最初版本的提案中规定,对于默认的实数运算,矩阵乘法的复杂度应做到 O(n2.3728596)(对于较小的 n 可以以更高的复杂度实现),这一规定遭到编译器厂商的一致反对;在最新版本提案中,这个要求放宽到了 O(n2.3728639),尚不清楚编译器厂商对此的态度。
类似的,STL 将加入 std::polynomial<class T, class ring, class Container = vector<T>> 作为内置的多项式类,其将包括多项式乘法、开根、求对数、求指数等操作。
整数字面量将支持英文、中文和罗马数字,例如 0ethirty_four、0c四十二、0rIX。旧版提案中,0r0 将会得到 Not a Number;但由于 Not a Number 已经被移除,代码中出现 0r0 将导致编译错误。
0s"x" 将可以定义在编译期计算的浮点字面量,例如 0s"2/3"、0s"1/ln(1.4)+exp(514)"。若系统时间足够早,这样的浮点字面量会不支持虚数;更早的系统时间将导致其不支持无理数。
这一特性同样遭到编译器厂商的反对,他们表示无法确定 0s"pi+e"、0s"pi-e"、0s"pi*e"、0s"pi/e" 中哪些不应通过编译,但 Pilar Lofo 博士暂未对此作出回应。
Bang 15 便士
让我们期待 C++23 拥有更多更加方便的新特性。