You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by ko...@apache.org on 2018/08/11 09:52:55 UTC

[arrow] branch master updated: ARROW-2979: [GLib] Add operator functions in GArrowDecimal128

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

kou 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 baff6d8  ARROW-2979: [GLib] Add operator functions in GArrowDecimal128
baff6d8 is described below

commit baff6d819b3634dac08a184a0402e888f8ca6b71
Author: Kouhei Sutou <ko...@clear-code.com>
AuthorDate: Sat Aug 11 18:52:38 2018 +0900

    ARROW-2979: [GLib] Add operator functions in GArrowDecimal128
    
    Author: Kouhei Sutou <ko...@clear-code.com>
    Author: yosuke shiro <ys...@gmail.com>
    
    Closes #2370 from shiro615/add-garrow-decimal128-operator-functions and squashes the following commits:
    
    b88a80a1 <Kouhei Sutou>  add missing Ruby/GObjectIntrospection version check
    8524203a <Kouhei Sutou>  Fix wrong expected value
    736773f2 <Kouhei Sutou>  Assert related values at once
    b401b747 <Kouhei Sutou>  Use more meaningful name
    5268f90a <Kouhei Sutou>  add missing Ruby/GObjectIntrospection version check
    d8e3e9ef <Kouhei Sutou>  make remainder nullable
    af4b4fc6 <Kouhei Sutou>  Fix transfer type
    a510d501 <yosuke shiro> Unify divide() and remainder()
    913dc1b9 <yosuke shiro> Add test_divide_zero
    326e4a3d <yosuke shiro> Use different numbers for decimal1 and decimal2 in test case
    5a9bedec <yosuke shiro> Use Divide() method
    aded1639 <yosuke shiro> Fix comments
    1cc14760 <yosuke shiro>  Add operator functions in GArrowDecimal128
---
 c_glib/arrow-glib/decimal.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++
 c_glib/arrow-glib/decimal.h   |  10 ++++
 c_glib/test/test-decimal.rb   |  54 ++++++++++++++++++++++
 3 files changed, 169 insertions(+)

diff --git a/c_glib/arrow-glib/decimal.cpp b/c_glib/arrow-glib/decimal.cpp
index 9c0cf03..79bf7e4 100644
--- a/c_glib/arrow-glib/decimal.cpp
+++ b/c_glib/arrow-glib/decimal.cpp
@@ -22,6 +22,7 @@
 #endif
 
 #include <arrow-glib/decimal.hpp>
+#include <arrow-glib/error.hpp>
 
 G_BEGIN_DECLS
 
@@ -217,6 +218,110 @@ garrow_decimal128_to_integer(GArrowDecimal128 *decimal)
   return static_cast<int64_t>(*arrow_decimal);
 }
 
+/**
+ * garrow_decimal128_plus:
+ * @left: A #GArrowDecimal128.
+ * @right: A #GArrowDecimal128.
+ *
+ * Returns: (transfer full): The added value of these decimals.
+ *
+ * Since: 0.11.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_plus(GArrowDecimal128 *left,
+                       GArrowDecimal128 *right)
+{
+  auto arrow_decimal_left = garrow_decimal128_get_raw(left);
+  auto arrow_decimal_right = garrow_decimal128_get_raw(right);
+  auto arrow_decimal =
+    std::make_shared<arrow::Decimal128>(*arrow_decimal_left + *arrow_decimal_right);
+  return garrow_decimal128_new_raw(&arrow_decimal);
+}
+
+/**
+ * garrow_decimal128_minus:
+ * @left: A #GArrowDecimal128.
+ * @right: A #GArrowDecimal128.
+ *
+ * Returns: (transfer full): The subtracted value of these decimals.
+ *
+ * Since: 0.11.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_minus(GArrowDecimal128 *left,
+                        GArrowDecimal128 *right)
+{
+  auto arrow_decimal_left = garrow_decimal128_get_raw(left);
+  auto arrow_decimal_right = garrow_decimal128_get_raw(right);
+  auto arrow_decimal =
+    std::make_shared<arrow::Decimal128>(*arrow_decimal_left - *arrow_decimal_right);
+  return garrow_decimal128_new_raw(&arrow_decimal);
+}
+
+/**
+ * garrow_decimal128_multiply:
+ * @left: A #GArrowDecimal128.
+ * @right: A #GArrowDecimal128.
+ *
+ * Returns: (transfer full): The multiplied value of these decimals.
+ *
+ * Since: 0.11.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_multiply(GArrowDecimal128 *left,
+                           GArrowDecimal128 *right)
+{
+  auto arrow_decimal_left = garrow_decimal128_get_raw(left);
+  auto arrow_decimal_right = garrow_decimal128_get_raw(right);
+  auto arrow_decimal =
+    std::make_shared<arrow::Decimal128>(*arrow_decimal_left * *arrow_decimal_right);
+  return garrow_decimal128_new_raw(&arrow_decimal);
+}
+
+/**
+ * garrow_decimal128_divide:
+ * @left: A #GArrowDecimal128.
+ * @right: A #GArrowDecimal128.
+ * @remainder: (out) (nullable): A return location for the remainder
+ *   value of these decimals. The returned #GArrowDecimal128 be
+ *   unreferred with g_object_unref() when no longer needed.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable) (transfer full): The divided value of
+ *   these decimals or %NULL on error.
+ *
+ * Since: 0.11.0
+ */
+GArrowDecimal128 *
+garrow_decimal128_divide(GArrowDecimal128 *left,
+                         GArrowDecimal128 *right,
+                         GArrowDecimal128 **remainder,
+                         GError **error)
+{
+  auto arrow_decimal_left = garrow_decimal128_get_raw(left);
+  auto arrow_decimal_right = garrow_decimal128_get_raw(right);
+  arrow::Decimal128 arrow_result_raw;
+  arrow::Decimal128 arrow_remainder_raw;
+  auto status =
+    arrow_decimal_left->Divide(*arrow_decimal_right,
+                               &arrow_result_raw,
+                               &arrow_remainder_raw);
+  if (garrow_error_check(error, status, "[decimal][divide]")) {
+    if (remainder) {
+      auto arrow_remainder =
+        std::make_shared<arrow::Decimal128>(arrow_remainder_raw);
+      *remainder = garrow_decimal128_new_raw(&arrow_remainder);
+    }
+    auto arrow_result = std::make_shared<arrow::Decimal128>(arrow_result_raw);
+    return garrow_decimal128_new_raw(&arrow_result);
+  } else {
+    if (remainder) {
+      *remainder = NULL;
+    }
+    return NULL;
+  }
+}
+
 G_END_DECLS
 
 GArrowDecimal128 *
diff --git a/c_glib/arrow-glib/decimal.h b/c_glib/arrow-glib/decimal.h
index ba9e18d..918cf3d 100644
--- a/c_glib/arrow-glib/decimal.h
+++ b/c_glib/arrow-glib/decimal.h
@@ -43,5 +43,15 @@ gchar *garrow_decimal128_to_string(GArrowDecimal128 *decimal);
 void garrow_decimal128_abs(GArrowDecimal128 *decimal);
 void garrow_decimal128_negate(GArrowDecimal128 *decimal);
 gint64 garrow_decimal128_to_integer(GArrowDecimal128 *decimal);
+GArrowDecimal128 *garrow_decimal128_plus(GArrowDecimal128 *left,
+                                         GArrowDecimal128 *right);
+GArrowDecimal128 *garrow_decimal128_minus(GArrowDecimal128 *left,
+                                          GArrowDecimal128 *right);
+GArrowDecimal128 *garrow_decimal128_multiply(GArrowDecimal128 *left,
+                                             GArrowDecimal128 *right);
+GArrowDecimal128 *garrow_decimal128_divide(GArrowDecimal128 *left,
+                                           GArrowDecimal128 *right,
+                                           GArrowDecimal128 **remainder,
+                                           GError **error);
 
 G_END_DECLS
diff --git a/c_glib/test/test-decimal.rb b/c_glib/test/test-decimal.rb
index 2528883..99f1912 100644
--- a/c_glib/test/test-decimal.rb
+++ b/c_glib/test/test-decimal.rb
@@ -16,6 +16,8 @@
 # under the License.
 
 class TestDecimal128 < Test::Unit::TestCase
+  include Helper::Omittable
+
   def test_to_string_scale
     integer_data = 23423445
     string_data = "234.23445"
@@ -52,4 +54,56 @@ class TestDecimal128 < Test::Unit::TestCase
     decimal = Arrow::Decimal128.new(integer_data)
     assert_equal(integer_data, decimal.to_i)
   end
+
+  def test_plus
+    integer_data1 = 23423445
+    integer_data2 = 5443
+    decimal1 = Arrow::Decimal128.new(integer_data1)
+    decimal2 = Arrow::Decimal128.new(integer_data2)
+    decimal3 = decimal1.plus(decimal2)
+    assert_equal(integer_data1 + integer_data2, decimal3.to_i)
+  end
+
+  def test_minus
+    integer_data1 = 23423445
+    integer_data2 = 5443
+    decimal1 = Arrow::Decimal128.new(integer_data1)
+    decimal2 = Arrow::Decimal128.new(integer_data2)
+    decimal3 = decimal1.minus(decimal2)
+    assert_equal(integer_data1 - integer_data2, decimal3.to_i)
+  end
+
+  def test_multiply
+    integer_data1 = 23423445
+    integer_data2 = 5443
+    decimal1 = Arrow::Decimal128.new(integer_data1)
+    decimal2 = Arrow::Decimal128.new(integer_data2)
+    decimal3 = decimal1.multiply(decimal2)
+    assert_equal(integer_data1 * integer_data2, decimal3.to_i)
+  end
+
+  def test_divide
+    require_gi_bindings(3, 3, 0)
+    integer_data1 = 23423445
+    integer_data2 = -5443
+    decimal1 = Arrow::Decimal128.new(integer_data1)
+    decimal2 = Arrow::Decimal128.new(integer_data2)
+    result, remainder = decimal1.divide(decimal2)
+    assert_equal([
+                   integer_data1.quo(integer_data2).truncate,
+                   integer_data1.remainder(integer_data2),
+                 ],
+                 [result.to_i, remainder.to_i])
+  end
+
+  def test_divide_zero
+    require_gi_bindings(3, 3, 0)
+    decimal1 = Arrow::Decimal128.new(23423445)
+    decimal2 = Arrow::Decimal128.new(0)
+    message =
+      "[decimal][divide]: Invalid: Division by 0 in Decimal128"
+    assert_raise(Arrow::Error::Invalid.new(message)) do
+      decimal1.divide(decimal2)
+    end
+  end
 end