As a general rule, we can take any value of any number type, and divide it by any non-zero value of any number type, and get a reasonable result.
212.7 / 6 // Double = 35.449999999999996
77L / 2.1F // Float = 36.666668
The one exception, that I've found, is that we can't mix a BigInt
with a fractional type (Float
or Double
).
In the realm of generics, however, there's this interesting distinction between Integral
and Fractional
types.
// 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)
While I am curious as to why this is, the real question is: Is there some kind of workaround available to sidestep this limitation?
The reason is because integer division and float division are two very different operations, so all Numerics
do not share a common division operation, although humans might think of them both as "division."
The workaround would be to create 4 division operations: Integral/Integral, Integral/Fractional, Fractional/Integral, Fractional/Fractional. Do the calculation in whatever application-specific way you feel is appropriate. When I did this for a calculator I wrote, I kept it in Integral if possible, and cast to Double otherwise.
My understanding is that these traits describe sets closed under defined operations:
Numeric
is closed under plus
, minus
, times
, negate
,
Fractional
adds div
(i.e. plus
, minus
, times
, negate
, div
),
Integral
adds quot
and rem
(i.e. plus
, minus
, times
, negate
, quot
, rem
).
Why do you want to sidestep it?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With