【问题标题】:How to calculate -1 modulo 1000000007 in C++如何在 C++ 中计算 -1 模 1000000007
【发布时间】:2014-09-27 21:37:52
【问题描述】:

我尝试使用 C++ 的 % 运算符得到 -1 模 1000000007 的结果 和fmod 函数。
输出是-1,但是-1 modulo 1000000007==1000000006

我做错了什么?

【问题讨论】:

    标签: c++ algorithm modulo


    【解决方案1】:

    说白了,你选错了运算符。

    C++ 和 C % 不是模数,而是余数。

    assert(a / b * b + a % b == a); // for integral types
    

    如果a 为非负数,则模数和余数相同。

    否则返回值为负,加​​b即可。

    template<class T>
    inline constexpr auto
    modulo(T a, T b) -> decltype(a%b) {
        auto r = a % b;
        if (r < 0) r += b;
        return r;
    }
    

    或者(也)对于 C:

    #define modulo(a, b) (a % b < 0 ? a % b + b : a % b)
    

    为了完整性:在 C++11 之前,a / b 可以始终向下舍入而不是始终为 0,尽管 C++03 已经注意到下一个标准可能会要求舍入为 0。

    See Wikipedia on modulo:

    模是欧几里得除法的余数,并且总是在范围 0

    And on remainder:

    在数学中,余数是执行一些计算后“剩余”的数量。

    【讨论】:

    • a/b 有一个相应的定义,当% 执行您调用的模数运算时,a/b * b + a%b == a 成立。在 C++11 之前,a/ba%b 的具体定义是实现定义的。 C++11 现在指定除法提供向零截断的代数商,这排除了 % 是您调用的模运算。
    • 现在我明白了其中的区别。你能在 C++ 中展示模数的示例用法吗
    • 应对a &lt; 0 &amp;&amp; b &lt; 0,建议if (r&lt;0) { m = r &lt; 0 ? m - r : m + r; }而不是if(r&lt;0) r += b;
    • 在 C 中,% 结果的符号与被除数或零的符号相同。对于模,您希望符号与除数或零的符号相同。所以你可以对除数和余数的符号位进行异或运算,如果余数不为零且符号不同,则将除数与余数相加。
    • @Deduplicator - 如果 a 为正且 b 为负,则 C 的余数与模数不同(应在 {b+1 -> 0} 范围内。例如 10%( -3) 在 C 中是 +1,而 10 模 (-3) 是 -2。在数学上,如果 C 将除法四舍五入到负无穷而不是零会更好,那么余数将与模相同,但大多数计算机向零舍入,所以 C 也顺其自然。许多 C / C++ 参考文献也将 % 称为模运算符。APL,一种可追溯到 1960 年代的语言具有正确的模运算符。
    【解决方案2】:

    处理负除数和正除数的模函数:

    template<class T>
    inline constexpr auto
    modulo(T a, T b) -> decltype(a%b) {
        auto r = a % b;
        if((b > 0 && r < 0) || (b < 0 && r > 0))
            r += b;
        return r;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-13
      • 2017-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 2017-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多