Skip to content
Snippets Groups Projects
Commit 3977223a authored by Sean Zhong's avatar Sean Zhong Committed by Wenchen Fan
Browse files

[SPARK-17617][SQL] Remainder(%) expression.eval returns incorrect result on double value

## What changes were proposed in this pull request?

Remainder(%) expression's `eval()` returns incorrect result when the dividend is a big double. The reason is that Remainder converts the double dividend to decimal to do "%", and that lose precision.

This bug only affects the `eval()` that is used by constant folding, the codegen path is not impacted.

### Before change
```
scala> -5083676433652386516D % 10
res2: Double = -6.0

scala> spark.sql("select -5083676433652386516D % 10 as a").show
+---+
|  a|
+---+
|0.0|
+---+
```

### After change
```
scala> spark.sql("select -5083676433652386516D % 10 as a").show
+----+
|   a|
+----+
|-6.0|
+----+
```

## How was this patch tested?

Unit test.

Author: Sean Zhong <seanzhong@databricks.com>

Closes #15171 from clockfly/SPARK-17617.
parent 7654385f
No related branches found
No related tags found
No related merge requests found
......@@ -310,7 +310,11 @@ case class Remainder(left: Expression, right: Expression)
if (input1 == null) {
null
} else {
integral.rem(input1, input2)
input1 match {
case d: Double => d % input2.asInstanceOf[java.lang.Double]
case f: Float => f % input2.asInstanceOf[java.lang.Float]
case _ => integral.rem(input1, input2)
}
}
}
}
......
......@@ -175,6 +175,17 @@ class ArithmeticExpressionSuite extends SparkFunSuite with ExpressionEvalHelper
}
}
test("SPARK-17617: % (Remainder) double % double on super big double") {
val leftDouble = Literal(-5083676433652386516D)
val rightDouble = Literal(10D)
checkEvaluation(Remainder(leftDouble, rightDouble), -6.0D)
// Float has smaller precision
val leftFloat = Literal(-5083676433652386516F)
val rightFloat = Literal(10F)
checkEvaluation(Remainder(leftFloat, rightFloat), -2.0F)
}
test("Abs") {
testNumericDataTypes { convert =>
val input = Literal(convert(1))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment