Scala Двойное сохранение и детерминированное чтение из двоичного файла - PullRequest
1 голос
/ 26 мая 2020

Как мне сделать Scala сохранить Double в двоичный файл и прочитать его с без потери точности?

Scala уже имеет хорошую основу для сохранения Double в текстовый файл, закодированный как представление String в базе 10. Однако это приводит к ошибке округления. Преобразование IEEE 754 64-битной плавающей точки в десятичное является несовершенным и вызывает небольшую ошибку округления. Моделирование, которое «копируется» на диск каждые два часа, а затем перезагружается с диска и возобновляется, не будет детерминированным c. Моделирование, которое было оставлено запущенным, будет отличаться от моделирования, которое было приостановлено и возобновлено из файла. Ваши мысли?

Ответы [ 3 ]

1 голос
/ 26 мая 2020

Чтобы решить эту проблему, я думаю, вам следует использовать BigDecimal

Меры предосторожности

  • Конструктор BigDecimal(String) всегда должен быть предпочтительнее BigDecimal(Double), потому что использование BigDecimal(double) непредсказуемо из-за неспособности double представить 0,1 как точную 0,1.

  • Если для инициализации BigDecimal необходимо использовать double, используйте BigDecimal.valueOf(double), который преобразует значение Double для String с использованием метода Double.toString(double)

  • При настройке масштаба должен быть обеспечен режим округления

  • StripTrailingZeros отрубается все конечные нули

  • toString() могут использовать научную c нотацию, но toPlainString() никогда не вернет возведение в степень в своем результате

По этой ссылке:

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

0 голосов
/ 28 мая 2020

Следуя предложению 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()
0 голосов
/ 26 мая 2020

Вы можете сохранять десятичные дроби в двоичном формате как есть побайтно:

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