C++ 为什么不是';标准C+中的t`int pow(int base,int exponent)`+;图书馆?

C++ 为什么不是';标准C+中的t`int pow(int base,int exponent)`+;图书馆?,c++,math,integer,standard-library,pow,C++,Math,Integer,Standard Library,Pow,我觉得我一定是找不到了。是否有任何理由,C++ POW函数不实现除“代码>浮点< /Cult> s和双< /Calp>S.以外的任何“幂”函数? 我知道实现是微不足道的,我只是觉得我在做应该在标准库中进行的工作。健壮的幂函数(即以某种一致、明确的方式处理溢出)编写起来并不有趣。因为无论如何都无法在int中表示所有整数幂: >>> print 2**-4 0.0625 对于任何固定宽度的整数类型,几乎所有可能的输入对都会溢出该类型。如果一个函数的绝大多数可能输入都不能给出有用

我觉得我一定是找不到了。是否有任何理由,C++ <代码> POW<代码>函数不实现除“代码>浮点< /Cult> s和<代码>双< /Calp>S.

以外的任何“幂”函数?
我知道实现是微不足道的,我只是觉得我在做应该在标准库中进行的工作。健壮的幂函数(即以某种一致、明确的方式处理溢出)编写起来并不有趣。

因为无论如何都无法在int中表示所有整数幂:

>>> print 2**-4
0.0625

对于任何固定宽度的整数类型,几乎所有可能的输入对都会溢出该类型。如果一个函数的绝大多数可能输入都不能给出有用的结果,那么标准化该函数有什么用呢

为了使函数有用,您几乎需要一个大整数类型,大多数大整数库都提供了该函数


编辑:在对该问题的评论中,static\u rtti写道“大多数输入导致它溢出?exp和double pow也是如此,我没有看到任何人抱怨。”这是不正确的

让我们把
exp
放在一边,因为这与重点无关(尽管这实际上会使我的案例更加有力),我们将重点放在
double-pow(double-x,double-y)
。对于(x,y)对的哪个部分,该函数做了有用的事情(即,不只是溢出或下溢)


实际上,我将只关注输入对的一小部分,
pow
对其有意义,因为这将足以证明我的观点:如果x为正且| y |,可能是因为处理器的ALU没有实现这样一个整数函数,但有这样一个FPU指令(正如Stephen所指出的,它实际上是一对)。因此,实际上转换为double、使用double调用pow、然后测试溢出和回滚比使用整数算法实现更快

(一方面,对数降低了乘法的幂次,但对于大多数输入,整数的对数会失去很多精度)


Stephen说得对,在现代处理器上,这不再是事实,但选择数学函数时的C标准(C++只是使用C函数)现在已经有20年的历史了?

C++11
,幂函数套件(和其他)中添加了特殊情况。
C++11[C.math]/11
在列出所有的
浮点/双精度/长双精度
重载(我的重点和释义)之后声明:

此外,应具有足够的额外重载,以确保如果与
double
参数对应的任何参数具有类型
double
或整数类型,则与
double
参数对应的所有参数都有效地转换为
double

因此,基本上,整数参数将升级为双倍以执行该操作


C++11
之前(当您被问及问题时),不存在整数重载

由于我与
C
C++
的创作者(尽管我已经很老了)都没有密切的联系,也不是创建标准的ANSI/ISO委员会的一员,这必然是我的观点。我想这是知情的观点,但正如我妻子告诉你的那样(经常而且不需要太多鼓励),我以前就错了:-)

假设,不管它值多少钱,随之而来

我怀疑最初的前ANSI
C
没有这个功能的原因是因为它完全没有必要。首先,已经有一种非常好的方法可以进行整数幂运算(使用双倍运算,然后简单地转换回整数,在转换前检查整数上溢和下溢)

其次,您必须记住的另一件事是,
C
的初衷是作为一种系统编程语言,而浮点运算在这一领域是否可取值得怀疑

由于它最初的一个用例是编写UNIX代码,因此浮点几乎是无用的。C语言所基于的BCPL也没有使用powers(它从内存中根本没有浮点)

另一方面,整数幂运算符可能是二进制运算符,而不是库调用。您不会用
x=add(y,z)
添加两个整数,而是用
x=y+z
添加两个整数,这是语言本身的一部分,而不是库

第三,由于integral-power的实现相对简单,几乎可以肯定,该语言的开发人员会更好地利用他们的时间提供更多有用的东西(参见下面关于机会成本的评论)

这也与原始的
C++
相关。由于原始实现实际上只是一个生成
C
代码的翻译器,它继承了
C
的许多属性。它的初衷是C-with-classes,而不是C-with-classes-plus-a-bit-extra-math-stuff

至于为什么在
C++11
之前从未将其添加到标准中,你必须记住,标准制定机构有具体的指导方针要遵循。例如,ANSI
C
专门负责编纂现有实践,而不是创建新的语言。否则,他们可能会发疯,给我们Ada:-)

该标准的后续版本也有具体的指南,可以在基本原理文件中找到(关于委员会为什么做出某些决定的基本原理,而不是语言本身的基本原理)

例如,
C99
基本原理文件具体继承了
C89
指导原则中的两项,这两项原则限制了可以添加的内容:

  • 保持语言简洁明了。
  • 仅提供一种执行操作的方法
G
5^-2 = 1/25

    // Computes x^n, where n is a natural number.
    double pown(double x, unsigned n)
    {
        double y = 1;
        // n = 2*d + r. x^n = (x^2)^d * x^r.
        unsigned d = n >> 1;
        unsigned r = n & 1;
        double x_2_d = d == 0? 1 : pown(x*x, d);
        double x_r = r == 0? 1 : x;
        return x_2_d*x_r;
    }
    // The linear implementation.
    double pown_l(double x, unsigned n)
    {
        double y = 1;
        for (unsigned i = 0; i < n; i++)
            y *= x;
        return y;
    }
double pown_auto(double x, unsigned n, double x_expected, unsigned n_expected) {
    if (x_expected < x_threshold)
        return pow(x, n);
    if (n_expected < n_threshold)
        return pown_l(x, n);
    return pown(x, n);
}
template<typename T>
static constexpr inline T pown(T x, unsigned p) {
    T result = 1;

    while (p) {
        if (p & 0x1) {
            result *= x;
        }
        x *= x;
        p >>= 1;
    }

    return result;
}