【问题标题】:Scala Double save and read from a binary file deterministicallyScala Double 确定性地从二进制文件中保存和读取
【发布时间】:2020-09-13 02:45:38
【问题描述】:

如何让 Scala 将 Double 保存到二进制文件并以 不损失 的精度读取它?

Scala 已经有一个很好的框架,可以将 Double 保存到文本文件中,以 10 进制编码为字符串表示形式。但是,这样做会引入舍入错误。 IEEE 754 64 位浮点 点到十进制的转换不完善,并引入了轻微的舍入误差。每两个小时“备份”到磁盘然后从磁盘重新加载并恢复的模拟将不是确定性的。继续运行的模拟与从文件中暂停和恢复的模拟不同。你的想法?

【问题讨论】:

  • 你能使用像 BigDecimal 这样的任意精度格式吗?

标签: scala file binary double precision


【解决方案1】:

要解决这个问题,我认为你应该使用BigDecimal

注意事项

  • BigDecimal(String) 构造函数应始终优先于 BigDecimal(Double),因为使用 BigDecimal(double) 是不可预测的,因为双精度无法将 0.1 表示为精确的 0.1。

  • 如果必须使用 double 来初始化 BigDecimal,请使用 BigDecimal.valueOf(double),它使用 Double.toString(double) 方法将 Double 值转换为字符串

  • 设置比例时应提供舍入模式

  • StripTrailingZeros 删除所有尾随零

  • toString() 可以使用科学记数法,但toPlainString() 永远不会在其结果中返回指数

参考这个链接:

https://dzone.com/articles/never-use-float-and-double-for-monetary-calculatio

【讨论】:

    【解决方案2】:

    您可以按原样以二进制格式保存小数:

    val fos: OutputStream = ???
    val out = new DataOutputStream(fos)
    out.writeDouble(1.0)
    

    【讨论】:

    • 我正在寻找的这个 DataOutputStream。我将在底部发布一个示例。感谢您对这个问题的回答。
    • @KseniaSemenova 欢迎您!如果答案解决了您的问题,您应该接受并投票,而不是用您的名义重写并稍作更正。我不是在寻找声誉,只是澄清 SO 的工作原理。
    【解决方案3】:

    按照 simpadjo 的建议,

    val sn:List[Double] = List(
              -4.2745321334280,-0.8827640054242,
              0.5781790299989,-2.5173973937094,
              4.3955017758756);
    val outputstm:OutputStream = new FileOutputStream( "numbers.bin" )
    val dos:DataOutputStream = new DataOutputStream(outputstm)
    for( k <- sn ) dos.writeDouble(k)
    dos.close()
    outputstm.close()
    

    【讨论】:

      猜你喜欢
      • 2019-11-20
      • 1970-01-01
      • 1970-01-01
      • 2013-05-22
      • 1970-01-01
      • 2015-02-05
      • 2014-10-18
      • 2017-10-18
      • 2018-09-11
      相关资源
      最近更新 更多