【问题标题】:Euclidean integer modulo in C++C ++中的欧几里得整数模
【发布时间】:2012-07-27 17:03:58
【问题描述】:

在哪里可以找到计算整数欧几里得除法余数的实现或库0 <= r < |n|

【问题讨论】:

    标签: c++ math integer division modulo


    【解决方案1】:

    这是一个简单的运算符。 %。

    5 % 4 为 1,以此类推

    编辑: 正如已经指出的那样,根据您的实现,这不一定是欧几里得模型。

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

    【讨论】:

    • 请注意,这只适用于整数。如果您想要浮点模数,请使用fmod 函数。 fmod (3.3, 2.4) is 0.9
    • 不,我说的是欧几里得除法。 (-5)%4 是 -1 但应该是 3。正如我在问题中所说,余数 r 应该在 0 和 n 之间,在我的示例中它是负数。
    • @NaomiJO,如果你真的需要,你可以将a % b 中的b 添加到结果中(如果它是否定的)。
    • 这实际上是不正确的。在大多数实现中,除法会将结果截断为零 - 这是非欧几里得除法。这意味着% 的结果可能是否定的:这已经是非欧几里得了。
    • 由于两个% 操作涉及整数除法,此方法不必要的慢。可以构造@AnT 答案的无分支版本,它只使用单个% 操作。
    【解决方案2】:

    在 C++ 98 和 C++03 版本的 C++ 语言中,内置除法(位 /% 运算符)可能是欧几里得,也可能是非欧几里得 - 它是实现定义的。然而,大多数实现将商截断为零,不幸的是,这是非欧几里得

    在大多数实现中5 / -3 = -15 % -3 = -2。在欧几里得除法5 / -3 = -25 % -3 = 1

    C++11 要求整数除法是非欧几里得:它需要一个向零截断的实现。

    如您所见,问题仅出现在负数上。因此,您可以通过使用运算符% 和后校正负余数轻松实现欧几里得除法

    int euclidean_remainder(int a, int b)
    {
      assert(b != 0);
      int r = a % b;
      return r >= 0 ? r : r + std::abs(b);
    }
    

    【讨论】:

      【解决方案3】:

      Try (x%m + m)%m if the result must be positive.

      围绕这个或任何变体编写您自己的函数,并且不要挂在库上 - 您花在询问上的时间比只做它要多。为您需要的简单功能创建自己的库(工具箱)。

      【讨论】:

      • 是的,谢谢。没有实现这个功能的库吗?这似乎相当普遍......
      • 由于两个% 操作涉及整数除法,此方法不必要的慢。可以构建@AnT 答案的无分支版本,它只使用单个% 操作。
      【解决方案4】:

      我真的很喜欢 Brandon 的回答,但我开始遇到一些奇怪的错误。 经过一些测试,我发现 EUCMOD 宏的扩展扰乱了操作的优先级。

      所以我建议将其用作函数而不是宏

      int eucmod(const int a, const int b)
      {
          return (a < 0 ? (((a % b) + b) % b) : (a % b));
      }
      

      或者加几个括号

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

      【讨论】:

        猜你喜欢
        • 2014-02-04
        • 2010-11-11
        • 2013-03-02
        • 1970-01-01
        • 2017-01-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多