>我有一个数据框,其中包含两列类型为 BigInt。然后我有一个用户定义的函数,它对这两列执行操作,最终结果应该是Float类型。
def generateNewColumnValue(firstColumnValue: BigInt, secondColumnValue: BigInt): Float = {
val calculated = scala.math.pow(firstColumnValue.toFloat / secondColumnValue, 1.0/3.0);
return calculated;
}
val generateNewColumnValueUDF = udf[Float, BigInt, BigInt](generateNewColumnValue);
如您所见,在 UDF 的主体内部,我正在做一些非常简单的计算。问题是我收到以下错误,我不明白为什么不可能:
command-836521033094408:9: error: overloaded method value / with alternatives:
(x: Double)Double <and>
(x: Float)Float <and>
(x: Long)Float <and>
(x: Int)Float <and>
(x: Char)Float <and>
(x: Short)Float <and>
(x: Byte)Float
cannot be applied to (BigInt)
val calculated = scala.math.pow(firstColumnValue.toFloat / secondColumnValue, 1.0/3.0);
问题是,如果我尝试将其转换为较低范围的类型(如 Int(,我可能会在小数点后丢失一些值。
该消息只是说您可以将Float
除以Double
、Float
等,但不能除以BigInt
。对两个操作数(而不仅仅是一个操作数(调用toFloat
:
firstColumnValue.toFloat / secondColumnValue.toFloat
但是math.pow
需要Double
s,而不是Float
s,所以toDouble
更有意义。 如果结果必须Float
,则根据pow
的结果调用toFloat
,而不是它的参数。
或者经历BigDecimal
:
(BigDecimal(firstColumnValue) / BigDecimal(secondColumnValue)).toDouble
在大多数情况下,它应该给出与第一个选项大致相同的结果,但速度较慢; 问题是BigInt
s可能太大,以至于firstColumnValue.toDouble
返回Double.PositiveInfinity
/NegativeInfinity
。您可以检查这一点,并且在这种情况下仅使用第二个选项。