1. ホーム
  2. c++

[解決済み] C/C++/Obj-Cで負の数を扱うモジュロ(%)演算子をコーディングする方法

2023-04-24 13:44:27

質問

C言語由来の言語で(数学者として)私が最も嫌いなものの1つは、以下の点です。

(-1) % 8 // comes out as -1, and not 7

fmodf(-1,8) // fails similarly

最適な解決策は?

C++はテンプレートと演算子のオーバーロードの可能性を認めていますが、この両方は私にとって泥沼です。

どのように解決するのですか?

まず最初に注意しておきたいのは、このように (-1) % 8 == -1 .あなたが頼れる唯一のものは (x / y) * y + ( x % y) == x . ただし、余りが負になるかどうかは 実装で定義されています。 .

参照 C++03 5.6 項の 4:

二項演算子 / は商を、二項演算子 % は最初の式を二番目の式で割った余りを出力します。もし、/や%の2番目のオペランドが0であれば、動作は不定です。そうでなければ、(a/b)*b + a%bはaに等しいです。もし、両方のオペランドが非負であれば、余りは非負になります。 でない場合、余りの符号は実装で定義されたものです。 .

ここでは、両方の負のオペランドを処理するバージョンに従いますので、引き算の結果である 余り から 除数 から引くことができる。 配当 となるので となり、実際の割り算の mod(-1,8) の結果は 7、一方 mod(13, -8) は-3です。

int mod(int a, int b)
{
   if(b < 0) //you can check for b == 0 separately and do what you want
     return -mod(-a, -b);   
   int ret = a % b;
   if(ret < 0)
     ret+=b;
   return ret;
}