This is an automated email from the ASF dual-hosted git repository.

praveenbingo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new 8bbfdc4  ARROW-10234: [C++][Gandiva] Fix logic of round() for 
floats/decimals in Gandiva
8bbfdc4 is described below

commit 8bbfdc42f529bcef80b31cbe2373f0132249f610
Author: Sagnik Chakraborty <[email protected]>
AuthorDate: Mon Oct 12 12:12:31 2020 +0530

    ARROW-10234: [C++][Gandiva] Fix logic of round() for floats/decimals in 
Gandiva
    
    This patch attempts to resolve the bug introduced by the addition of 
round() in ARROW-9641
    
    round() for floats is returning incorrect results for some edge cases, like 
round(cast(1.55 as float), 1) gives 1.6, but it should be 1.5, since the result 
after casting 1.55 to float comes to 1.5499999523162842, due to inaccurate 
representation of floating point numbers in memory.
    
    Removing an intermediate explicit cast to float statement for a double 
value, which is used in subsequent computations, minimises the error introduced 
due to the incorrect representation.
    
    Closes #8398 from sagnikc-dremio/round-double and squashes the following 
commits:
    
    b1ef5438a <Sagnik Chakraborty> ARROW-10234:  Fix logic of round() for 
floats/decimals in Gandiva
    
    Authored-by: Sagnik Chakraborty <[email protected]>
    Signed-off-by: Praveen <[email protected]>
---
 cpp/src/gandiva/precompiled/extended_math_ops.cc      | 3 +--
 cpp/src/gandiva/precompiled/extended_math_ops_test.cc | 4 ++++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/cpp/src/gandiva/precompiled/extended_math_ops.cc 
b/cpp/src/gandiva/precompiled/extended_math_ops.cc
index 3329acc..686d447 100644
--- a/cpp/src/gandiva/precompiled/extended_math_ops.cc
+++ b/cpp/src/gandiva/precompiled/extended_math_ops.cc
@@ -116,8 +116,7 @@ POWER(float64, float64, float64)
 #define ROUND_DECIMAL(TYPE)                                                 \
   FORCE_INLINE                                                              \
   gdv_##TYPE round_##TYPE##_int32(gdv_##TYPE number, gdv_int32 out_scale) { \
-    gdv_##TYPE scale_multiplier =                                           \
-        static_cast<gdv_##TYPE>(get_scale_multiplier(out_scale));           \
+    gdv_float64 scale_multiplier = get_scale_multiplier(out_scale);         \
     return static_cast<gdv_##TYPE>(                                         \
         trunc(number * scale_multiplier + ((number > 0) ? 0.5 : -0.5)) /    \
         scale_multiplier);                                                  \
diff --git a/cpp/src/gandiva/precompiled/extended_math_ops_test.cc 
b/cpp/src/gandiva/precompiled/extended_math_ops_test.cc
index fcbefe1..fb51342 100644
--- a/cpp/src/gandiva/precompiled/extended_math_ops_test.cc
+++ b/cpp/src/gandiva/precompiled/extended_math_ops_test.cc
@@ -93,6 +93,10 @@ TEST(TestExtendedMathOps, TestRoundDecimal) {
   EXPECT_FLOAT_EQ(round_float32_int32(-1234.4567f, 3), -1234.457f);
   EXPECT_FLOAT_EQ(round_float32_int32(-1234.4567f, -3), -1000);
   EXPECT_FLOAT_EQ(round_float32_int32(1234.4567f, 0), 1234);
+  EXPECT_FLOAT_EQ(round_float32_int32(1.5499999523162842f, 1), 1.5f);
+  EXPECT_FLOAT_EQ(round_float32_int32(static_cast<float>(1.55), 1), 1.5f);
+  EXPECT_FLOAT_EQ(round_float32_int32(static_cast<float>(9.134123), 2), 9.13f);
+  EXPECT_FLOAT_EQ(round_float32_int32(static_cast<float>(-1.923), 1), -1.9f);
 
   VerifyFuzzyEquals(round_float64_int32(1234.789, 2), 1234.79);
   VerifyFuzzyEquals(round_float64_int32(1234.12345, -3), 1000);

Reply via email to