【问题标题】:Divide two BigInt values and cast the result to Float in Scala将两个 BigInt 值相除并将结果转换为 Scala 中的 Float
【发布时间】:2020-02-12 21:22:41
【问题描述】:

我有一个包含 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),我可能会在小数点后丢失一些值。

【问题讨论】:

  • new BigDecimal(firstColumnValue).divide(secondColumnValue, roundingMode).toFloat(如果可以的话,最好是 .toDouble)
  • @Thilo BigInteger 不是 Scala 的一部分。我尝试使用 BigInt,但它不起作用。
  • 对于 Scala BigDecimal,你写 BigDecimal(firstColumnValue),而不是 new(除以 /,而不是 divide)。

标签: scala dataframe apache-spark-sql


【解决方案1】:

消息只是说您可以将Float 除以DoubleFloat 等,但不能除以BigInt。在两个操作数上调用toFloat,而不仅仅是一个:

firstColumnValue.toFloat / secondColumnValue.toFloat

但是math.pow 需要Doubles,而不是Floats,所以toDouble 更有意义。 如果结果必须是Float,请在pow 的结果上调用toFloat,而不是它的参数。

或者通过BigDecimal:

(BigDecimal(firstColumnValue) / BigDecimal(secondColumnValue)).toDouble

在大多数情况下,它应该给出与第一个选项大致相同的结果,但速度较慢;问题是BigInts 可能太大以至于firstColumnValue.toDouble 返回Double.PositiveInfinity/NegativeInfinity。你可以检查一下,在这种情况下只使用第二个选项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 2013-06-10
    • 2019-05-05
    相关资源
    最近更新 更多