web-dev-qa-db-ja.com

Scalaでは、なぜ剰余(%)演算子が負の数を返すのでしょうか?

たとえば、_(-3) % 2_は_-1_ではなく_1_を返します。

Scalaで正の剰余を取得する好ましい方法は何ですか? _(((-3) % 2) + 2) % 2_、またはabs(-3 % 2)など?

17
Hanfei Sun

Scalaでは、なぜ剰余(%)演算子が負の数を返すことができますか?

モジュロ演算の結果の符号にはさまざまな規則があります。 ウィキペディアには良い記事があります 。 Scalaは、ほとんどのプログラミング言語と同じですが、すべてのプログラミング言語ではありませんが、結果は配当の兆候(あなたの場合は_-3_)を取ります。

Scalaで正の剰余を取得する好ましい方法は何ですか?

一般的に認められている好ましい方法があるとは思わない。私なら、 _Math.floorMod_ を使用します。これは、被除数の代わりに除数の符号(例では_2_)で結果を与えます(これは単に_%_と同じ値を意味し、符号が異なります。詳細については、リンクされたJavaDocを参照してください)。または、後でifif (result < 0) { result += M; } [ここでMは除数、例では_2_)です)。

15
T.J. Crowder

正のモジュラスを取得する正しい方法は、負のモジュラスに除数を追加することです:

(-18 % 5) + 5

この場合、絶対値を取ると間違った解が得られますが、除数が2になった場合はうまくいきます。

配当の兆候がわからない場合は、次のようなことができます。

((dividend % divisor) + divisor) % divisor
12
Kevin

既存の回答に何かを追加したいと思います。正の剰余を取得するための好ましい方法は、次のようにInt型に新しいメソッドを追加することです。

object Extensions
{
    implicit class ExtendedInt (val i: Int) extends AnyVal {
        def positiveMod (m: Int) = {val x = i % m; if (x < 0) x + m else x}
    }
}

メソッドを使用するファイルで、次を使用して暗黙クラスをインポートします。

import Extensions._

できるようになりました:

(-3).positiveMod(2)

また、同じパッケージから関数を呼び出すときにインポートする必要がないように、暗黙的なクラスをパッケージオブジェクトに配置することもできます。

2
user42723

math.abs(-x % y)を使用しても、通常、正のモジュラスを返すのと同じ動作は得られません。

scala> math.abs(-7 % 3)
res46: Int = 1

しかし、それはpython(正のモジュラスを返す言語))が言うことではありません:

In [14]: -7 % 3
Out[14]: 2

-7から3の増分を見ると:

-7, -4, -1, 2, ..

scala-1で停止し、python2で停止します。

2
Akavall