C++ における負の数のモジュラス

Neha Imran 2023年10月12日
  1. 剰余対モジュラス
  2. C++ の % 演算子
  3. C++ での % の実装
  4. Python の % 演算子
  5. Python での % の実装
  6. C++ で Python の同等のモジュラスを達成する方法
C++ における負の数のモジュラス

このチュートリアルでは、剰余とモジュラスの違いを発見します。 % 演算子の基礎について学びます。

後で、% 演算子が Python と C++ でどのように動作するかを学習します。 最後に、C++ でモジュラス機能を実装するいくつかの方法について説明することで、この記事をまとめます。

剰余対モジュラス

% 記号の正確な動作は、プログラミング言語によって異なる場合があります。 オペレーターは、私たちを混乱させる驚くべき結果を頻繁に生み出します。

モジュラスまたは剰余を作成しますか? プログラミング言語での動作を調べる前に、まずそれらがどのように異なるかを明確にしましょう。

剰余

剰余は、単に 2つの整数の算術除算の後に残る部分です。 正でも負でも、剰余の符号は常に被除数の符号によって決まります。

以下の例を確認して、これを明確に理解してください。

例:

  1. 7% 3 = 1

    ここで被除数は 7 で正符号なので、結果も正符号になります。

  2. -7% 3 = -1

    ここで被除数は -7 で負符号なので、結果も負符号になります。

  3. 7% -3 = 1

    ここで被除数は 7 で正符号なので、結果も正符号になります。

  4. -7% -3 = -1

    ここで被除数は -7 で負符号なので、結果も負符号になります。

係数

モジュラスは、符号が逆の場合は剰余と除数の和であり、剰余と除数が同じ符号の場合は算術除算後の剰余です。

モジュラスは、除数と同じ符号になります。 以下の例を確認して、これを明確に理解してください。

例:

  1. 5% 3 = 2

    ここでは、除数と剰余の両方が正符号であるため、剰余も正符号になります。

  2. -5% 3 = 1

    ここで、除数と剰余は逆符号であるため、結果は剰余と除数の和になります。 すなわち -2 + 3 = 1

  3. 5% -3 = -1

    ここで、除数と剰余は逆符号です。 結果は剰余と除数の合計になります。 つまり、2 + -3 = -1

  4. -5% -3 = -2

    ここでは、除数と剰余の符号が同じであるため、結果は剰余と同じになります。

上記の例から明らかなように、被除数と除数の両方が正の場合、剰余と剰余は同じです。 負の数の場合、両者は異なります。

この時点で、剰余とモジュラスがどのように異なるかが明確になることを願っています。 それでは、Python と C++ での % 演算子の動作について話しましょう。

C++ の % 演算子

C++ では、% はモジュロ演算子として知られています。 算術演算子です。

これは、整数除算を実行した結果の剰余を計算するために使用されます。 モジュロという名前が付いていますが、覚えておくべき重要なことは、モジュラスを提供しないということです。

C++ では、% 記号は剰余のみを返します。 以下の例を確認してください。

#include <iostream>
using namespace std;
int main() {
  cout << -7 % 3 << endl;
  cout << 7 % -3 << endl;
}

出力:

-1
 1

出力が示すように、% 演算子はモジュラスを与えません。 残りを返すだけです。

C++ での % の実装

C++ での % の実装を見てみましょう。 C++ の剰余は、次の式に従って返されます。

残り = a - ( b * trunc ( a / b ) )

% 演算子を使用せずに上記の式を使用して剰余を計算するためのロジックを開発しましょう。

#include <iostream>
using namespace std;

int calRemainder(int a, int b) {
  int q = a / b;
  return a - (b * q);
}
int main() {
  int a = -7, b = 3;
  cout << calRemainder(a, b) << endl;
}

出力:

-1

Python の % 演算子

Python では、% はモジュロ演算子として知られています。 モジュロ演算子は、Python では算術演算と見なされます。

これは、整数除算の結果である modulus を計算するために使用されます。 ここが Python と C++ の違いです。

C++ で剰余演算子を使用すると剰余が返されますが、Python では剰余が返されます。 以下の例をチェックして、Python での剰余演算子の動作を確認してください。

print(-7 % 3)
print(7 % -3)

出力:

 2
-2

最初の例では、-7 % 3 は剰余 -1 を返します。 剰余 (-1) と除数 (3) は反対の符号であるため、それらの合計はモジュラスになります。 つまり -1 + 3 = 2.

例 2 についても同様です。

Python での % の実装

Python での % の実装を見てみましょう。 Python のモジュラスは、次の式に従って返されます。

モジュラス = a - ( b * 床 ( a / b ) )

% 演算子を使用せずに上記の式を使用してモジュラスを計算するためのロジックを開発しましょう。

from math import floor


def calModulus(a, b):
    q = floor(a / b)
    return a - b * q


print(calModulus(-7, 3))

出力:

2

C++ で Python の同等のモジュラスを達成する方法

Python と C++ で剰余とモジュラスがどのように異なり、% 演算子がどのように動作するかを調べました。 Python では、% を正の除数とともに使用すると、常に非負の値が得られます。

ほとんどの場合、正の除数を使用します。剰余だけでなく、モジュラスの機能が必要です。 除数が正の符号の場合、モジュラスは常に正の値を返します。

C++ でこの動作を実現するためのさまざまな手法を見てみましょう。

方法 1: 方程式を実装する

C++ で式 modulus = a - ( b * floor( a / b ) ) を実装することで、Python モジュラスの動作を実現できます。

#include <math.h>

#include <iostream>
using namespace std;

int getModulus(int dividend, int divisor) {
  // Type casting is necessary as (int)/(int) will give int result, i.e. -5 / 2
  // will give -1 and not -2.5
  int t = (int)floor((double)dividend / divisor);
  return dividend - divisor * t;
}

int main() { cout << getModulus(-8, 3); }

出力:

1

方法 2: 剰余と除数を加算する

C++ でモジュラス機能を実現するもう 1つの方法は、剰余と除数の符号が逆の場合に加算することです。

除数は正符号であると想定しているため、剰余が負の場合は除数に加算してモジュラス値を取得します。

#include <iostream>
using namespace std;

int getModulus(int dividend, int divisor) {
  int t = dividend % divisor;
  return t >= 0 ? t : t + divisor;
}

int main() { cout << getModulus(-7, 3); }

出力:

2

関連記事 - C++ Modulo