为啥我的 std::pow 和 std::fmod 结果错误? [复制]

Posted

技术标签:

【中文标题】为啥我的 std::pow 和 std::fmod 结果错误? [复制]【英文标题】:Why I get wrong result with std::pow and std::fmod? [duplicate]为什么我的 std::pow 和 std::fmod 结果错误? [复制] 【发布时间】:2018-01-31 20:19:48 【问题描述】:

下面这几行代码在计算后返回错误的结果,会不会是“double”类型的逼近造成的?

    int base = 20, exp = 27, mod = 123;
    std::fmod(std::pow(base, exp), mod)

有没有办法得到正确的计算? (也有 base = 128,Exp >= 50 mod >= 200?) 对不起我的英语不好

【问题讨论】:

正确的计算方法是什么?你得到了什么? 有一个可以应用的数学定律,即result = result*base % mod 循环exp 次将给出与base<sup>exp</sup> % mod 相同的结果。不过不记得叫什么了。无论如何,它可以让你计算巨大的数字并且永远不会留下整数空间。 当调用std::fmod 时,您的变量将提升为double,并且该类型对于您的测试用例没有足够的精度:ideone.com/hBbKyV。如果你需要计算更大的值,你应该利用模运算。 【参考方案1】:

您的问题是浮点错误。传入pow()时,数字转换为双精度数,双精度数可以存储54位有效二进制数字,不足以准确存储20^27。最好通过像这样重复 result = result * base % mod exp 次来利用模运算:

int result = 1;
for(int i = 0; i < exp; i++)

    result = result * base % mod;

只要输入不是太大,这应该将值保持在 int 限制之下并在几秒钟内运行。如需更快的算法,请使用binary exponentiation。

【讨论】:

以上是关于为啥我的 std::pow 和 std::fmod 结果错误? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

c++11 下 fmod(和其他)的不同行为,至少在 Visual Studio 中

标准对 std::pow、std::log 等 cmath 函数有啥看法?

static_assert 中的 std::pow 触发错误 C2057?

计算 p^q(求幂)的有效方法,其中 q 是整数

875. 快速幂

为啥我的画布和/或我的照片图像不显示?