作为一般规则,我们可以取任何数字类型的任何值,并将其除以任何数字类型的任何非零值,并获得合理的结果。
212.7 / 6 // Double = 35.449999999999996
77L / 2.1F // Float = 36.666668
我发现的一个例外是,我们无法将BigInt
与小数类型(Float
或Double
)混合。
然而,在泛型领域,Integral
和Fractional
类型之间存在这种有趣的区别。
// 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)
虽然我 好奇为什么会这样,但真正的问题是:是否有某种解决方法可以回避这个限制?
答案 0 :(得分:5)
原因是因为整数除法和浮点除法是两个非常不同的运算,所以所有Numerics
都不共享一个共同的除法运算,尽管人类可能会认为它们都是“除法。“
解决方法是创建4个除法运算:积分/积分,积分/分数,分数/积分,分数/分数。以您认为合适的任何特定于应用程序的方式进行计算。当我为我编写的计算器执行此操作时,如果可能的话,我将其保留在Integral中,否则将其转换为Double。
答案 1 :(得分:3)
我的理解是这些特征描述了在定义的操作下关闭的集合:
Numeric
已在plus
,minus
,times
,negate
,
Fractional
添加div
(即plus
,minus
,times
,negate
,div
),
Integral
添加了quot
和rem
(即plus
,minus
,times
,negate
,{{1} },quot
)。
你为什么要回避它?