【问题标题】:Scala - convert large or scientific numbers to LongScala - 将大数或科学数转换为 Long
【发布时间】:2018-06-21 06:21:01
【问题描述】:

需要能够将 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

【问题讨论】:

    标签: java scala long-integer biginteger bigdecimal


    【解决方案1】:

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

    要可靠地将这些字符串转换为Longs,您可以尝试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
    

    你可以玩弄这个小sn-p代码here on Scastie

    【讨论】:

    • new BigDecimal("20006916941148201619.00000000").longValue() 给出错误结果 (1560172867438650003)。还有其他选择吗?
    • 该值太大而无法以 64 位长存储,您必须使用 BigDecimal/BigInteger。或者您可以创建自己的类型并使用字节数组支持它,但您需要自己处理。
    【解决方案2】:
    val signNumber = Try(numberCleaner(signNumber).replaceAll("\\.[0-9]*$", "").toLong.toString).getOrElse(numberCleaner(signNumber).toDouble.toLong.toString)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-24
      • 2015-07-03
      • 1970-01-01
      • 2018-09-24
      • 2020-11-09
      • 1970-01-01
      • 2014-09-25
      • 2021-12-23
      相关资源
      最近更新 更多