为什么我的 std::pow 整数数学给出了错误的答案?

2022-01-09 00:00:00 floating-point g++ c++

考虑以下代码:

#include <iostream>
#include <cmath>

int main() {
    int i = 23;
    int j = 1;
    int base = 10;
    int k = 2;
    i += j * pow(base, k);
    std::cout << i << std::endl;
}

它输出122"而不是123".它是 g++ 4.7.2 (MinGW, Windows XP) 中的错误吗?

It outputs "122" instead of "123". Is it a bug in g++ 4.7.2 (MinGW, Windows XP)?

推荐答案

std::pow() 适用于浮点数,它没有无限精度,并且您使用的标准库的实现可能实现 pow() 以一种(较差的)方式使这种缺乏无限精度变得相关.

std::pow() works with floating point numbers, which do not have infinite precision, and probably the implementation of the Standard Library you are using implements pow() in a (poor) way that makes this lack of infinite precision become relevant.

但是,您可以轻松定义自己的整数版本.在 C++11 中,您甚至可以将其设为 constexpr(以便尽可能在编译时计算结果):

However, you could easily define your own version that works with integers. In C++11, you can even make it constexpr (so that the result could be computed at compile-time when possible):

constexpr int int_pow(int b, int e)
{
    return (e == 0) ? 1 : b * int_pow(b, e - 1);
}

这是一个现场示例.

尾递归形式(归功于 Dan Nissenbaum):

Tail-recursive form (credits to Dan Nissenbaum):

constexpr int int_pow(int b, int e, int res = 1)
{
    return (e == 0) ? res : int_pow(b, e - 1, b * res);
}

相关文章