Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
914 views
in Technique[技术] by (71.8m points)

scala - Generic Numeric division

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...