Точность искры десятичного типа - PullRequest
5 голосов
/ 07 марта 2019

Я проверяю искровые десятичные типы для валютных показателей и вижу некоторые странные результаты точности, когда я устанавливаю масштаб и точность, как показано ниже. Я хочу быть уверен, что у меня не будет потери данных во время вычислений, но приведенный ниже пример не подтверждает это. Может кто-нибудь сказать мне, почему это происходит с искрой SQL? В настоящее время на версии 2.3.0

val sql = """select cast(cast(3 as decimal(38,14)) / cast(9 as decimal(38,14)) as decimal(38,14)) val"""
spark.sql(sql).show

Возвращает

+----------------+
|             val|
+----------------+
|0.33333300000000|
+----------------+

Ответы [ 2 ]

1 голос
/ 19 марта 2019

Это текущий открытый выпуск, см. SPARK-27089 .Предлагаемое решение состоит в том, чтобы отрегулировать настройки ниже.Я проверил, что оператор SQL работает, как и ожидалось, с этим параметром, установленным в false.

spark.sql.decimalOperations.allowPrecisionLoss=false
0 голосов
/ 12 марта 2019

Используйте BigDecimal, чтобы избежать потери точности. См. Двойной против BigDecimal?

пример:

scala> val df = Seq(BigDecimal("0.03"),BigDecimal("8.20"),BigDecimal("0.02")).toDS
df: org.apache.spark.sql.Dataset[scala.math.BigDecimal] = [value: decimal(38,18)]

scala> df.select($"value").show
+--------------------+
|               value|
+--------------------+
|0.030000000000000000|
|8.200000000000000000|
|0.020000000000000000|
+--------------------+

Использование BigDecimal:

scala> df.select($"value" + BigDecimal("0.1")).show
+-------------------+
|      (value + 0.1)|
+-------------------+
|0.13000000000000000|
|8.30000000000000000|
|0.12000000000000000|
+-------------------+

Если вы не используете BigDecimal, потеря точности будет. В этом случае 0,1 является двойной

scala> df.select($"value" +  lit(0.1)).show
+-------------------+
|      (value + 0.1)|
+-------------------+
|               0.13|
|  8.299999999999999|
|0.12000000000000001|
+-------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...