2016-10-31 12 views
4

一般的に、任意の数値型の任意の値をとり、任意の数値型の非ゼロ値で除算し、妥当な結果を得ることができます。一般的な数値除算

212.7/6 // Double = 35.449999999999996 
77L/2.1F // Float = 36.666668 

唯一の例外は、私が見つけたことを、私たちは分数の種類(FloatまたはDouble)でBigIntを混在させることができないということです。

しかしながら、ジェネリックの領域では、IntegralFractionalのタイプの間にこの興味深い違いがあります。

// can do this 
def divideI[I](a: I, b: I)(implicit ev: Integral[I]) = ev.quot(a,b) 

// or this 
def divideF[F](a: F, b: F)(implicit ev: Fractional[F]) = ev.div(a,b) 

// but not this 
def divideN[N](a: N, b: N)(implicit ev: Numeric[N]) = ev.???(a,b) 

私はこれが理由として好奇心午前ながら、本当の問題は次のようになります。この制限を回避するために利用可能な回避策のいくつかの種類がありますか?

答えて

1

私の理解では、これらの特性が定義された操作の下で閉じセットについて説明していることである:

Fractional

div追加

Numericは、negatetimesminusplusの下で閉じている(すなわちplusminustimesnegatediv)、

Integralは、quotrem(すなわち、 plus,minus,times,negate,quot,rem)。

なぜそれを回避しますか?整数の除算とフロート部門は2 非常に異なる操作であるため、

+0

私は、ユーザ(呼び出しコード)を 'Integral'または' Fractional'に制限することなく、プリミティブ型で行うことができるのと同じ(多かれ少なかれ)簡単な数学演算を実行したいと考えています。実装を隠しながら(結果を得るための数学演算)、ユーザーに最も広い入力オプション(任意の数値)を与えたいと思います。数学演算が '+'、 ' - '、 '*'に限定されているなら、簡単に行うことができます。 '/'がその集合に含まれていないことは奇妙に思えます。 – jwvh

3

理由は、人間のようにそれらの両方を考えるかもしれませんが、その全てNumericsは、一般的な除算演算を共有していない「部門。」

回避策は、整数/整数、整数/分数、分数/整数、分数/分数の4つの除算演算を作成することです。適切なアプリケーション固有の方法で計算を行います。私が書いた電卓のためにこれをしたとき、可能ならIntegralに保存し、そうでなければDoubleにキャストしました。

+0

はい、数値型を知っているIFFで動作するので、Numericにはできません。実際には、コンパイラはメソッドのオーバーロードを許可しない(つまり、それらの型のメソッドパラメータを区別できない)ため、IntegralまたはFractionalは使用できません。任意の数値型に対して「数学を行う」メソッドを使用するには、ジェネリック型を省略し、数値型のすべての合理的な組み合わせ(プリミティブ)に対してメソッドをオーバーロードする必要があるように見えます。 – jwvh

関連する問題