【问题标题】:Can't use modulus on doubles?不能在双打上使用模数?
【发布时间】:2012-02-26 16:03:57
【问题描述】:

我有一个 C++ 程序(使用 g++ 编译)。我正在尝试将两个双精度数作为操作数应用于模函数,但出现以下错误:

错误:“double”和“double”类型的无效操作数到二进制“operator%”

代码如下:

int main() {
    double x = 6.3;
    double y = 2;
    double z = x % y;
}

【问题讨论】:

  • 如前所述,fmod() 提供了必要的功能。正如尚未注意到的那样,重要的是要意识到fmod 的第二个操作数中的舍入错误可能会导致意外行为。例如,fmod(1, 0.1); 在数学上应该为零,但实际上几乎是 0.1。误差的程度随着商的大小而增加。例如,fmod(9E14, 0.1); 的计算结果约为 0.05,从数学角度来看这是完全错误的。
  • @supercat 更多细节会很棒。我认为对幕后发生的事情使您所说的话有所了解,但是最好了解您所说的话是真实的原因;看看它在幕后是如何工作的会很有趣(我想我理解但很容易出错)。
  • 浮点值表示精确的整数倍数或 2 的幂的分数。例如,整数文字 0.1 正好是 3602879701896397/36028797018963968(后一个值是 2 的幂)。 fmod(x,0.1) 将 x 除以该精确分数并取余数,而不是除以数值“十分之一”。

标签: c++ modulo


【解决方案1】:

% 运算符用于整数。您正在寻找fmod() function

#include <cmath>

int main()
{
    double x = 6.3;
    double y = 2.0;
    double z = std::fmod(x,y);

}

【讨论】:

  • 我正在使用 C++ 为 Qt 编程,而 fmod 有一个错误。 fmod(angle, 360) 的结果可以是 360 (WAT?!)
  • @Paul:这可能不是错误。如果angle359.9999999,那么anglefmod(angle, 360) 都可能显示为360。 (根据需要添加更多 9。)尝试以 50 位精度打印值。
  • @Paul Qt 的 QString::format 将四舍五入。如果这很关键,您将不得不自己四舍五入或检查“360”的输出并将其替换为您自己的值。
  • @Rohan main(void)C++ 中是不必要的(它是 C 遗留),您的编辑也没有改进其他任何东西。我把它恢复了。
【解决方案2】:

fmod(x, y) 是你使用的函数。

【讨论】:

    【解决方案3】:

    使用&lt;cmath&gt; 中的fmod()。如果不想包含 C 头文件:

    template<typename T, typename U>
    constexpr double dmod (T x, U mod)
    {
        return !mod ? x : x - mod * static_cast<long long>(x / mod);
    }
    
    //Usage:
    double z = dmod<double, unsigned int>(14.3, 4);
    double z = dmod<long, float>(14, 4.6);
    //This also works:
    double z = dmod(14.7, 0.3);
    double z = dmod(14.7, 0);
    double z = dmod(0, 0.3f);
    double z = dmod(myFirstVariable, someOtherVariable);
    

    【讨论】:

    • 为什么不想包含 C 头文件?这就是它的用途。
    【解决方案4】:

    你可以实现你自己的模数函数来为你做这件事:

    double dmod(double x, double y) {
        return x - (int)(x/y) * y;
    }
    

    然后您可以简单地使用dmod(6.3, 2) 来获得余数,0.3

    【讨论】:

    • 仍然不是一个完美的解决方案。 x=10.499999999999998, y=0.69999999999999996 返回 0.69999999999999929 而不是 0.0
    • @tarpista:这是预期的,带有浮点数。
    猜你喜欢
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多