9

Objective-C でモジュロ演算を行ったときに得られる結果に、私は少しびっくりしています。-1 % 3 は -1 になりますが、これは正しい答えではありません。私の理解では、2 になるはずです。-2 % 3 は -2 になりますが、これも正しくありません。 1になります。

正しい結果を得るために % 演算子以外に使用すべき別の方法はありますか?

4

6 に答える 6

7

Objective-CはC99のスーパーセットであり、C99はが負のa % b場合に負であると定義しますaモジュロ演算に関するウィキペディアのエントリこのStackOverflowの質問も参照してください。

(a >= 0) ? (a % b) : ((a % b) + b)(テストされておらず、おそらく不要な括弧が付いている)のようなもので、希望する結果が得られるはずです。

于 2010-03-12T05:59:49.540 に答える
3

スペンサー、MOD について考える簡単な方法があります (プログラミングではなく、数学で定義されている方法です)。それは実際にはかなり簡単です:

すべての整数を取ります:

...-9、-8、-7、-6、-5、-4、-3、-2、-1、0、1、2、3、4、5、6、7、8、9 . ..

次に、3 の倍数について考えてみましょう ( mod 3を検討している場合)。0 と 3 の正の倍数から始めましょう。

...- 9 、-8 、 -7、 -6 、 -5 、-4、 -3 、 -2 、-1、0、1、2、3、4、5、6、7、8、9 . ..

これらはすべて、3 で割ったときに余りがゼロになる数です。つまり、これらはすべて mod でゼロになる数です。

では、このグループ全体を 1 つ上にシフトしましょう。

...-9、-8、 -7 、 -6 、-5、 -4 、-3 、-2、-1、0、1、2、3、4、5、6、7、8、9 . ..

これらはすべて、3 で割ると 1 余りになる数です。つまり、これらはすべて mod で 1 になる数です。

ここで、このグループ全体を 1 つ上にシフトしましょう。

...-9、 -8 、-7、 -6 、 -5 、-4、 -3 、 -2、-1、0、1、2、3、4、5、6、7、8、9 。 ..

これらはすべて、3 で割ると 2 余りになる数です。つまり、これらはすべて 2 に mod される数です。

これらのケースのそれぞれで、選択された数値が 3 間隔で配置されていることに気付くでしょう。モジュロ 3 を考慮しているため、常に 3 つおきの数値を使用します (mod 5 を実行している場合は、5 つおきの数値を使用します)。 .

したがって、このパターンを負の数に戻すことができます。間隔を 3 に保つだけです。次の 3 つの合同クラス(数学で呼ばれる特殊なタイプの等価クラス) が得られます。

... -9、 -8 、 -7 、-6、 -5 、 -4 、-3、 -2 、 -1 、0、 1 、 2 、3、 4 、 5 、6、 7 、 8 、9。 ..

...-9、-8 、 -7、-6、-5 -4、-3 、-2-1、0、1、2、3、4、5、6、7、8、9。 ..

...-9、-8、-7 -6 -5、-4、-3、-2-1、0、1、2、3、4、5、6、7、8、9。 ..

これらすべての同等の数の標準的な数学的表現は、クラスの剰余を使用することです。これは、負でない最小の数を取ることを意味します。

したがって、通常、mod について考えていて、負の数を扱っているときは、最初の 0 または正の数が得られるまで、モジュロ数を何度も何度も連続して追加することを考えます。

mod 3 を実行している場合、-1 を使用すると、3 を 1 回追加するだけです: -1 + 3 = 2. -4 を使用すると、1 回では不十分なので、3 を 2 回追加します。+3 を 1 回追加すると、-4 + 3 = -1 になりますが、これはまだ負です。+3 を追加します: -1 + 3 = 2.

-23 のような、より大きな負の数を試してみましょう。+3 を追加し続けると、次のようになります。

-23, -20, -17, -14, -11, -8, -5, -2, 1. 正の数を取得したので、終了します。剰余は 1 で、これは数学者が通常使用する形式です。

于 2013-01-04T06:34:08.647 に答える
2

ANSI C99 6.5.5 乗法演算子 -

6.5.5.5:/演算子の結果は、第 1 オペランドを第 2 オペランドで除算した商です。演算子の結果は%剰余です。どちらの操作でも、2 番目のオペランドの値がゼロの場合、動作は未定義です。

6.5.5.6: 整数が除算されると、/演算子の結果は小数部分が破棄された代数商になります (*90)。商a/bが表現可能な場合、式(a/b)*b + a%bは と等しくなりaます。

*90: これはしばしば「ゼロ方向への切り捨て」と呼ばれます。

あなたが考えているモジュロ動作のタイプは、「モジュラー算術」または「数論」スタイルのモジュロ/剰余と呼ばれます。剰余演算子の剰余算術/数論の定義を使用すると、負の結果が得られることは無意味です。これは (明らかに) C99 で定義および使用されているモジュロ動作のスタイルではありません。C99 の方法に「問題」はありません。それはあなたが期待していたものではありません。:)

于 2010-03-16T10:33:01.910 に答える
1

負の数のモジュロは、思ったほど簡単ではありません。http://mathforum.org/library/drmath/view/52343.htmlを参照してください

于 2010-03-12T05:46:51.347 に答える
1

私も同じ問題を抱えていましたが、うまくいきました!あなたがする必要があるのは、数が正か負かをチェックすることです、そしてそれが負であるならば、あなたはもう一つの数を加える必要があります:

//neg 
// -6 % 7 = 1
int testCount = (4 - 10);
if (testCount < 0) {
  int  moduloInt = (testCount % 7) + 7; // add 7
    NSLog(@"\ntest modulo: %d",moduloInt);
}
else{
  int moduloInt = testCount % 7;
    NSLog(@"\ntest modulo: %d",moduloInt);
}

// pos
// 1 % 7 = 1
int testCount = (6 - 5);
if (testCount < 0) {
  int  moduloInt = (testCount % 7) + 7; // add 7
    NSLog(@"\ntest modulo: %d",moduloInt);
}
else{
  int moduloInt = testCount % 7;
    NSLog(@"\ntest modulo: %d",moduloInt);
}

お役に立てば幸いです。A。

于 2013-01-10T23:31:02.193 に答える