Scala - 将大数或科学数转换为 Long

Scala - convert large or scientific numbers to Long

需要能够将 00000924843571390729101 或 2.71000000000000000E+02 转换为 Long 期望 2.71000000000000000E+02 变成 271

funky results for this: 00000924843571390729101 became 924843571390729088
val signNumber = "00000924843571390729101"

val castnum = signNumber.toDouble.toLong.toString

下面的第一个转换适用于 2.71000000000000000E+02,第二个适用于 00000924843571390729101

val castnum = signNumber.toDouble.toLong.toString
val castnum = signNumber.replaceAll("\.[0-9]*$", "").toLong.toString

不想保留任何小数位所以不使用 java.math.BigDecimal

输入字符串可能是 9028456928343.0000,在这种情况下需要 9028456928343 作为 Long

第一种情况的奇怪结果是由于您正在经历 toDouble,由于双精度的表示方式限制了精度。

要将这些字符串可靠地转换为 Long,您可以尝试 BigDecimal::longValueExact,如下所示:

import java.math.BigDecimal

new BigDecimal("00000924843571390729101").longValueExact()
// 924843571390729101: Long
new BigDecimal("9028456928343.0000").longValueExact()
// 9028456928343: Long
new BigDecimal("2.71000000000000000E+02").longValueExact()
// 271: Long

由于您还有带有十进制数字的字符串,因此您必须使用一种可以识别这些数字的解析形式,即使您不想保留该信息。

如果您丢失任何信息,此方法将抛出 ArithmeticInformation,这意味着该数字不适合 Long 或它具有非零小数部分。如果您想更宽松一些,可以使用 BigDecimal::longValue

import java.math.BigDecimal
import scala.util.Try

​Try(new BigDecimal("9028456928343.0001").longValueExact())
// Failure(java.lang.ArithmeticException: Rounding necessary): scala.util.Try
Try(new BigDecimal("9028456928343.0001").longValue())
// Success(9028456928343): scala.util.Try

您可以尝试一下这个小代码片段 here on Scastie

val signNumber = Try(numberCleaner(signNumber).replaceAll("\.[0-9]*$", "").toLong.toString).getOrElse(numberCleaner(signNumber).toDouble.toLong.toString)