Generic Numeric division

こ雲淡風輕ζ 提交于 2019-12-29 06:59:09

问题


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?


回答1:


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.




回答2:


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?



来源:https://stackoverflow.com/questions/40351176/generic-numeric-division

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!