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

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


The following commit(s) were added to refs/heads/main by this push:
     new c23ee7342c GH-44589: [GLib] Add GArrowDecimal32 class (#44597)
c23ee7342c is described below

commit c23ee7342c0c822f1458f892c60edfdd7ce857cc
Author: Hiroyuki Sato <[email protected]>
AuthorDate: Fri Nov 1 06:12:20 2024 +0900

    GH-44589: [GLib] Add GArrowDecimal32 class (#44597)
    
    
    
    ### Rationale for this change
    
    The `Decimal32` class has been introduced. It is necessary to support it in 
GLib.
    
    ### What changes are included in this PR?
    
    Implement `GArrowDecimal32` class
    
    ### Are these changes tested?
    
    YES
    
    ### Are there any user-facing changes?
    
    NO
    
    * GitHub Issue: #44589
    
    Authored-by: Hiroyuki Sato <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 c_glib/arrow-glib/decimal.cpp | 434 +++++++++++++++++++++++++++++++++++++++++-
 c_glib/arrow-glib/decimal.h   |  79 ++++++++
 c_glib/arrow-glib/decimal.hpp |   5 +
 c_glib/test/test-decimal32.rb | 222 +++++++++++++++++++++
 4 files changed, 739 insertions(+), 1 deletion(-)

diff --git a/c_glib/arrow-glib/decimal.cpp b/c_glib/arrow-glib/decimal.cpp
index edc2af7a7e..30b596f7a3 100644
--- a/c_glib/arrow-glib/decimal.cpp
+++ b/c_glib/arrow-glib/decimal.cpp
@@ -24,6 +24,24 @@ template <typename Decimal> struct DecimalConverter
 {
 };
 
+template <> struct DecimalConverter<arrow::Decimal32>
+{
+  using ArrowType = arrow::Decimal32;
+  using GArrowType = GArrowDecimal32;
+
+  GArrowType *
+  new_raw(std::shared_ptr<ArrowType> *arrow_decimal32)
+  {
+    return garrow_decimal32_new_raw(arrow_decimal32);
+  }
+
+  std::shared_ptr<ArrowType>
+  get_raw(GArrowType *decimal32)
+  {
+    return garrow_decimal32_get_raw(decimal32);
+  }
+};
+
 template <> struct DecimalConverter<arrow::Decimal64>
 {
   using ArrowType = arrow::Decimal64;
@@ -319,9 +337,11 @@ G_BEGIN_DECLS
 /**
  * SECTION: decimal
  * @section_id: decimal
- * @title: 64-bit, 128-bit and 256-bit decimal classes
+ * @title: 32-bit, 64-bit, 128-bit and 256-bit decimal classes
  * @include: arrow-glib/arrow-glib.h
  *
+ * #GArrowDecimal32 is a 32-bit decimal class.
+ *
  * #GArrowDecimal64 is a 64-bit decimal class.
  *
  * #GArrowDecimal128 is a 128-bit decimal class.
@@ -331,6 +351,403 @@ G_BEGIN_DECLS
  * Since: 0.10.0
  */
 
+typedef struct GArrowDecimal32Private_
+{
+  std::shared_ptr<arrow::Decimal32> decimal32;
+} GArrowDecimal32Private;
+
+enum {
+  PROP_DECIMAL32 = 1
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal32, garrow_decimal32, G_TYPE_OBJECT)
+
+#define GARROW_DECIMAL32_GET_PRIVATE(obj)                                      
          \
+  static_cast<GArrowDecimal32Private *>(                                       
          \
+    garrow_decimal32_get_instance_private(GARROW_DECIMAL32(obj)))
+
+static void
+garrow_decimal32_finalize(GObject *object)
+{
+  auto priv = GARROW_DECIMAL32_GET_PRIVATE(object);
+
+  priv->decimal32.~shared_ptr();
+
+  G_OBJECT_CLASS(garrow_decimal32_parent_class)->finalize(object);
+}
+
+static void
+garrow_decimal32_set_property(GObject *object,
+                              guint prop_id,
+                              const GValue *value,
+                              GParamSpec *pspec)
+{
+  auto priv = GARROW_DECIMAL32_GET_PRIVATE(object);
+
+  switch (prop_id) {
+  case PROP_DECIMAL32:
+    priv->decimal32 =
+      *static_cast<std::shared_ptr<arrow::Decimal32> 
*>(g_value_get_pointer(value));
+    break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    break;
+  }
+}
+
+static void
+garrow_decimal32_init(GArrowDecimal32 *object)
+{
+  auto priv = GARROW_DECIMAL32_GET_PRIVATE(object);
+  new (&priv->decimal32) std::shared_ptr<arrow::Decimal32>;
+}
+
+static void
+garrow_decimal32_class_init(GArrowDecimal32Class *klass)
+{
+  auto gobject_class = G_OBJECT_CLASS(klass);
+
+  gobject_class->finalize = garrow_decimal32_finalize;
+  gobject_class->set_property = garrow_decimal32_set_property;
+
+  GParamSpec *spec;
+  spec = g_param_spec_pointer(
+    "decimal32",
+    "Decimal32",
+    "The raw std::shared<arrow::Decimal32> *",
+    static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property(gobject_class, PROP_DECIMAL32, spec);
+}
+
+/**
+ * garrow_decimal32_new_string:
+ * @data: The data of the decimal.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable):
+ *   A newly created #GArrowDecimal32 on success, %NULL on error.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal32 *
+garrow_decimal32_new_string(const gchar *data, GError **error)
+{
+  return garrow_decimal_new_string<arrow::Decimal32>(data,
+                                                     error,
+                                                     
"[decimal32][new][string]");
+}
+
+/**
+ * garrow_decimal32_new_integer:
+ * @data: The data of the decimal.
+ *
+ * Returns: A newly created #GArrowDecimal32.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal32 *
+garrow_decimal32_new_integer(const gint64 data)
+{
+  return garrow_decimal_new_integer<arrow::Decimal32>(data);
+}
+
+/**
+ * garrow_decimal32_copy:
+ * @decimal: The decimal to be copied.
+ *
+ * Returns: (transfer full): A copied #GArrowDecimal32.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal32 *
+garrow_decimal32_copy(GArrowDecimal32 *decimal)
+{
+  return garrow_decimal_copy<arrow::Decimal32>(decimal);
+}
+
+/**
+ * garrow_decimal32_equal:
+ * @decimal: A #GArrowDecimal32.
+ * @other_decimal: A #GArrowDecimal32 to be compared.
+ *
+ * Returns: %TRUE if the decimal is equal to the other decimal, %FALSE
+ *   otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal32_equal(GArrowDecimal32 *decimal, GArrowDecimal32 
*other_decimal)
+{
+  return garrow_decimal_equal<arrow::Decimal32>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal32_not_equal:
+ * @decimal: A #GArrowDecimal32.
+ * @other_decimal: A #GArrowDecimal32 to be compared.
+ *
+ * Returns: %TRUE if the decimal isn't equal to the other decimal,
+ *   %FALSE otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal32_not_equal(GArrowDecimal32 *decimal, GArrowDecimal32 
*other_decimal)
+{
+  return garrow_decimal_not_equal<arrow::Decimal32>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal32_less_than:
+ * @decimal: A #GArrowDecimal32.
+ * @other_decimal: A #GArrowDecimal32 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal,
+ *   %FALSE otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal32_less_than(GArrowDecimal32 *decimal, GArrowDecimal32 
*other_decimal)
+{
+  return garrow_decimal_less_than<arrow::Decimal32>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal32_less_than_or_equal:
+ * @decimal: A #GArrowDecimal32.
+ * @other_decimal: A #GArrowDecimal32 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal
+ *   or equal to the other decimal, %FALSE otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal32_less_than_or_equal(GArrowDecimal32 *decimal,
+                                    GArrowDecimal32 *other_decimal)
+{
+  return garrow_decimal_less_than_or_equal<arrow::Decimal32>(decimal, 
other_decimal);
+}
+
+/**
+ * garrow_decimal32_greater_than:
+ * @decimal: A #GArrowDecimal32.
+ * @other_decimal: A #GArrowDecimal32 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal,
+ *   %FALSE otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal32_greater_than(GArrowDecimal32 *decimal, GArrowDecimal32 
*other_decimal)
+{
+  return garrow_decimal_greater_than<arrow::Decimal32>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal32_greater_than_or_equal:
+ * @decimal: A #GArrowDecimal32.
+ * @other_decimal: A #GArrowDecimal32 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal
+ *   or equal to the other decimal, %FALSE otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal32_greater_than_or_equal(GArrowDecimal32 *decimal,
+                                       GArrowDecimal32 *other_decimal)
+{
+  return garrow_decimal_greater_than_or_equal<arrow::Decimal32>(decimal, 
other_decimal);
+}
+
+/**
+ * garrow_decimal32_to_string_scale:
+ * @decimal: A #GArrowDecimal32.
+ * @scale: The scale of the decimal.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ *   It should be freed with g_free() when no longer needed.
+ *
+ * Since: 19.0.0
+ */
+gchar *
+garrow_decimal32_to_string_scale(GArrowDecimal32 *decimal, gint32 scale)
+{
+  return garrow_decimal_to_string_scale<arrow::Decimal32>(decimal, scale);
+}
+
+/**
+ * garrow_decimal32_to_string:
+ * @decimal: A #GArrowDecimal32.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ *   It should be freed with g_free() when no longer needed.
+ *
+ * Since: 19.0.0
+ */
+gchar *
+garrow_decimal32_to_string(GArrowDecimal32 *decimal)
+{
+  return garrow_decimal_to_string<arrow::Decimal32>(decimal);
+}
+
+/**
+ * garrow_decimal32_to_bytes:
+ * @decimal: A #GArrowDecimal32.
+ *
+ * Returns: (transfer full): The binary representation of the decimal.
+ *
+ * Since: 19.0.0
+ */
+GBytes *
+garrow_decimal32_to_bytes(GArrowDecimal32 *decimal)
+{
+  return garrow_decimal_to_bytes<arrow::Decimal32>(decimal);
+}
+
+/**
+ * garrow_decimal32_abs:
+ * @decimal: A #GArrowDecimal32.
+ *
+ * Computes the absolute value of the @decimal destructively.
+ *
+ * Since: 19.0.0
+ */
+void
+garrow_decimal32_abs(GArrowDecimal32 *decimal)
+{
+  garrow_decimal_abs<arrow::Decimal32>(decimal);
+}
+
+/**
+ * garrow_decimal32_negate:
+ * @decimal: A #GArrowDecimal32.
+ *
+ * Negate the current value of the @decimal destructively.
+ *
+ * Since: 19.0.0
+ */
+void
+garrow_decimal32_negate(GArrowDecimal32 *decimal)
+{
+  garrow_decimal_negate<arrow::Decimal32>(decimal);
+}
+
+/**
+ * garrow_decimal32_to_integer:
+ * @decimal: A #GArrowDecimal32.
+ *
+ * Returns: The 64-bit integer representation of the decimal.
+ *
+ * Since: 19.0.0
+ */
+gint64
+garrow_decimal32_to_integer(GArrowDecimal32 *decimal)
+{
+  auto arrow_decimal = garrow_decimal32_get_raw(decimal);
+  return static_cast<int64_t>(*arrow_decimal);
+}
+
+/**
+ * garrow_decimal32_plus:
+ * @left: A #GArrowDecimal32.
+ * @right: A #GArrowDecimal32.
+ *
+ * Returns: (transfer full): The added value of these decimals.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal32 *
+garrow_decimal32_plus(GArrowDecimal32 *left, GArrowDecimal32 *right)
+{
+  return garrow_decimal_plus<arrow::Decimal32>(left, right);
+}
+
+/**
+ * garrow_decimal32_minus:
+ * @left: A #GArrowDecimal32.
+ * @right: A #GArrowDecimal32.
+ *
+ * Returns: (transfer full): The subtracted value of these decimals.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal32 *
+garrow_decimal32_minus(GArrowDecimal32 *left, GArrowDecimal32 *right)
+{
+  return garrow_decimal_minus<arrow::Decimal32>(left, right);
+}
+
+/**
+ * garrow_decimal32_multiply:
+ * @left: A #GArrowDecimal32.
+ * @right: A #GArrowDecimal32.
+ *
+ * Returns: (transfer full): The multiplied value of these decimals.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal32 *
+garrow_decimal32_multiply(GArrowDecimal32 *left, GArrowDecimal32 *right)
+{
+  return garrow_decimal_multiply<arrow::Decimal32>(left, right);
+}
+
+/**
+ * garrow_decimal32_divide:
+ * @left: A #GArrowDecimal32.
+ * @right: A #GArrowDecimal32.
+ * @remainder: (out) (nullable): A return location for the remainder
+ *   value of these decimals. The returned #GArrowDecimal32 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: 19.0.0
+ */
+GArrowDecimal32 *
+garrow_decimal32_divide(GArrowDecimal32 *left,
+                        GArrowDecimal32 *right,
+                        GArrowDecimal32 **remainder,
+                        GError **error)
+{
+  return garrow_decimal_divide<arrow::Decimal32>(left,
+                                                 right,
+                                                 remainder,
+                                                 error,
+                                                 "[decimal32][divide]");
+}
+
+/**
+ * garrow_decimal32_rescale:
+ * @decimal: A #GArrowDecimal32.
+ * @original_scale: A scale to be converted from.
+ * @new_scale: A scale to be converted to.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable) (transfer full): The rescaled decimal or %NULL on error.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal32 *
+garrow_decimal32_rescale(GArrowDecimal32 *decimal,
+                         gint32 original_scale,
+                         gint32 new_scale,
+                         GError **error)
+{
+  return garrow_decimal_rescale<arrow::Decimal32>(decimal,
+                                                  original_scale,
+                                                  new_scale,
+                                                  error,
+                                                  "[decimal32][rescale]");
+}
 typedef struct GArrowDecimal64Private_
 {
   std::shared_ptr<arrow::Decimal64> decimal64;
@@ -1499,6 +1916,21 @@ garrow_decimal256_rescale(GArrowDecimal256 *decimal,
 
 G_END_DECLS
 
+GArrowDecimal32 *
+garrow_decimal32_new_raw(std::shared_ptr<arrow::Decimal32> *arrow_decimal32)
+{
+  auto decimal32 =
+    g_object_new(garrow_decimal32_get_type(), "decimal32", arrow_decimal32, 
NULL);
+  return GARROW_DECIMAL32(decimal32);
+}
+
+std::shared_ptr<arrow::Decimal32>
+garrow_decimal32_get_raw(GArrowDecimal32 *decimal32)
+{
+  auto priv = GARROW_DECIMAL32_GET_PRIVATE(decimal32);
+  return priv->decimal32;
+}
+
 GArrowDecimal64 *
 garrow_decimal64_new_raw(std::shared_ptr<arrow::Decimal64> *arrow_decimal64)
 {
diff --git a/c_glib/arrow-glib/decimal.h b/c_glib/arrow-glib/decimal.h
index bb266424b4..6f839a67d9 100644
--- a/c_glib/arrow-glib/decimal.h
+++ b/c_glib/arrow-glib/decimal.h
@@ -25,6 +25,85 @@
 
 G_BEGIN_DECLS
 
+/* Disabled because it conflicts with GARROW_TYPE_DECIMAL32 in GArrowType. */
+/* #define GARROW_TYPE_DECIMAL32 (garrow_decimal32_get_type()) */
+GARROW_AVAILABLE_IN_19_0
+G_DECLARE_DERIVABLE_TYPE(GArrowDecimal32, garrow_decimal32, GARROW, DECIMAL32, 
GObject)
+
+struct _GArrowDecimal32Class
+{
+  GObjectClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal32 *
+garrow_decimal32_new_string(const gchar *data, GError **error);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal32 *
+garrow_decimal32_new_integer(const gint64 data);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal32 *
+garrow_decimal32_copy(GArrowDecimal32 *decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal32_equal(GArrowDecimal32 *decimal, GArrowDecimal32 
*other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal32_not_equal(GArrowDecimal32 *decimal, GArrowDecimal32 
*other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal32_less_than(GArrowDecimal32 *decimal, GArrowDecimal32 
*other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal32_less_than_or_equal(GArrowDecimal32 *decimal,
+                                    GArrowDecimal32 *other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal32_greater_than(GArrowDecimal32 *decimal, GArrowDecimal32 
*other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal32_greater_than_or_equal(GArrowDecimal32 *decimal,
+                                       GArrowDecimal32 *other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gchar *
+garrow_decimal32_to_string_scale(GArrowDecimal32 *decimal, gint32 scale);
+GARROW_AVAILABLE_IN_19_0
+gchar *
+garrow_decimal32_to_string(GArrowDecimal32 *decimal);
+GARROW_AVAILABLE_IN_19_0
+GBytes *
+garrow_decimal32_to_bytes(GArrowDecimal32 *decimal);
+GARROW_AVAILABLE_IN_19_0
+void
+garrow_decimal32_abs(GArrowDecimal32 *decimal);
+GARROW_AVAILABLE_IN_19_0
+void
+garrow_decimal32_negate(GArrowDecimal32 *decimal);
+GARROW_AVAILABLE_IN_19_0
+gint64
+garrow_decimal32_to_integer(GArrowDecimal32 *decimal);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal32 *
+garrow_decimal32_plus(GArrowDecimal32 *left, GArrowDecimal32 *right);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal32 *
+garrow_decimal32_minus(GArrowDecimal32 *left, GArrowDecimal32 *right);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal32 *
+garrow_decimal32_multiply(GArrowDecimal32 *left, GArrowDecimal32 *right);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal32 *
+garrow_decimal32_divide(GArrowDecimal32 *left,
+                        GArrowDecimal32 *right,
+                        GArrowDecimal32 **remainder,
+                        GError **error);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal32 *
+garrow_decimal32_rescale(GArrowDecimal32 *decimal,
+                         gint32 original_scale,
+                         gint32 new_scale,
+                         GError **error);
+
 /* Disabled because it conflicts with GARROW_TYPE_DECIMAL64 in GArrowType. */
 /* #define GARROW_TYPE_DECIMAL64 (garrow_decimal64_get_type()) */
 GARROW_AVAILABLE_IN_ALL
diff --git a/c_glib/arrow-glib/decimal.hpp b/c_glib/arrow-glib/decimal.hpp
index dbfb7f30c6..09ac40a512 100644
--- a/c_glib/arrow-glib/decimal.hpp
+++ b/c_glib/arrow-glib/decimal.hpp
@@ -25,6 +25,11 @@
 
 #include <arrow-glib/decimal.h>
 
+GArrowDecimal32 *
+garrow_decimal32_new_raw(std::shared_ptr<arrow::Decimal32> *arrow_decimal32);
+std::shared_ptr<arrow::Decimal32>
+garrow_decimal32_get_raw(GArrowDecimal32 *decimal);
+
 GArrowDecimal64 *
 garrow_decimal64_new_raw(std::shared_ptr<arrow::Decimal64> *arrow_decimal64);
 std::shared_ptr<arrow::Decimal64>
diff --git a/c_glib/test/test-decimal32.rb b/c_glib/test/test-decimal32.rb
new file mode 100644
index 0000000000..33b84ccc6b
--- /dev/null
+++ b/c_glib/test/test-decimal32.rb
@@ -0,0 +1,222 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+class TestDecimal32 < Test::Unit::TestCase
+  def test_new_string_invalid
+    message =
+      "[decimal32][new][string]: Invalid: " +
+      "The string '1,1' is not a valid decimal32 number"
+    error = assert_raise(Arrow::Error::Invalid) do
+      Arrow::Decimal32.new("1,1")
+    end
+    assert_equal(message,
+                 error.message.lines.first.chomp)
+  end
+
+  def test_copy
+    decimal = Arrow::Decimal32.new("234.23445")
+    assert_equal(decimal, decimal.copy)
+  end
+
+  def test_to_string_scale
+    integer_data = 23423445
+    string_data = "234.23445"
+    decimal = Arrow::Decimal32.new(integer_data)
+    assert_equal(string_data, decimal.to_string_scale(5))
+  end
+
+  def test_to_string
+    string_data = "999999999"
+    decimal = Arrow::Decimal32.new(string_data)
+    assert_equal(string_data, decimal.to_s)
+  end
+
+  def test_to_bytes
+    decimal = Arrow::Decimal32.new("12.3")
+    assert_equal("\x7B\x00\x00\x00",
+                 decimal.to_bytes.to_s)
+  end
+
+  def test_abs
+    absolute_value = "230492239"
+    negative_value = "-230492239"
+    decimal = Arrow::Decimal32.new(negative_value)
+    decimal.abs
+    assert_equal(absolute_value, decimal.to_s)
+  end
+
+  def test_negate
+    positive_value = "230492239"
+    negative_value = "-230492239"
+    decimal = Arrow::Decimal32.new(positive_value)
+    decimal.negate
+    assert_equal(negative_value, decimal.to_s)
+    decimal.negate
+    assert_equal(positive_value, decimal.to_s)
+  end
+
+  def test_plus
+    integer_data1 = 23423445
+    integer_data2 = 5443
+    decimal1 = Arrow::Decimal32.new(integer_data1)
+    decimal2 = Arrow::Decimal32.new(integer_data2)
+    decimal3 = decimal1.plus(decimal2)
+    assert_equal((integer_data1 + integer_data2).to_s,
+                 decimal3.to_s)
+  end
+
+  def test_multiply
+    integer_data1 = 23423
+    integer_data2 = 5443
+    decimal1 = Arrow::Decimal32.new(integer_data1)
+    decimal2 = Arrow::Decimal32.new(integer_data2)
+    decimal3 = decimal1.multiply(decimal2)
+    assert_equal((integer_data1 * integer_data2).to_s,
+                 decimal3.to_s)
+  end
+
+  def test_divide
+    integer_data1 = 23423
+    integer_data2 = -5443
+    decimal1 = Arrow::Decimal32.new(integer_data1)
+    decimal2 = Arrow::Decimal32.new(integer_data2)
+    result, remainder = decimal1.divide(decimal2)
+    assert_equal([
+                   integer_data1.quo(integer_data2).truncate.to_s,
+                   integer_data1.remainder(integer_data2).to_s,
+                 ],
+                 [result.to_s, remainder.to_s])
+  end
+
+  def test_divide_zero
+    decimal1 = Arrow::Decimal32.new(23423445)
+    decimal2 = Arrow::Decimal32.new(0)
+    message =
+      "[decimal32][divide]: Invalid: Division by 0 in Decimal32"
+    assert_raise(Arrow::Error::Invalid.new(message)) do
+      decimal1.divide(decimal2)
+    end
+  end
+
+  def test_equal
+    decimal = Arrow::Decimal32.new(10)
+    other_decimal1 = Arrow::Decimal32.new(10)
+    other_decimal2 = Arrow::Decimal32.new(11)
+    assert_equal([
+                   true,
+                   false,
+                 ],
+                 [
+                   decimal == other_decimal1,
+                   decimal == other_decimal2,
+                 ])
+  end
+
+  def test_not_equal
+    decimal = Arrow::Decimal32.new(10)
+    other_decimal1 = Arrow::Decimal32.new(10)
+    other_decimal2 = Arrow::Decimal32.new(11)
+    assert_equal([
+                   false,
+                   true,
+                 ],
+                 [
+                   decimal != other_decimal1,
+                   decimal != other_decimal2,
+                 ])
+  end
+
+  def test_less_than
+    decimal = Arrow::Decimal32.new(10)
+    other_decimal1 = Arrow::Decimal32.new(11)
+    other_decimal2 = Arrow::Decimal32.new(9)
+    assert_equal([
+                   true,
+                   false,
+                   false
+                 ],
+                 [
+                   decimal < other_decimal1,
+                   decimal < other_decimal2,
+                   decimal < decimal,
+                 ])
+  end
+
+  def test_less_than_or_equal
+    decimal = Arrow::Decimal32.new(10)
+    other_decimal1 = Arrow::Decimal32.new(11)
+    other_decimal2 = Arrow::Decimal32.new(9)
+    assert_equal([
+                   true,
+                   false,
+                   true
+                 ],
+                 [
+                   decimal <= other_decimal1,
+                   decimal <= other_decimal2,
+                   decimal <= decimal
+                 ])
+  end
+
+  def test_greater_than
+    decimal = Arrow::Decimal32.new(10)
+    other_decimal1 = Arrow::Decimal32.new(11)
+    other_decimal2 = Arrow::Decimal32.new(9)
+    assert_equal([
+                   false,
+                   true,
+                   false
+                 ],
+                 [
+                   decimal > other_decimal1,
+                   decimal > other_decimal2,
+                   decimal > decimal
+                 ])
+  end
+
+  def test_greater_than_or_equal
+    decimal = Arrow::Decimal32.new(10)
+    other_decimal1 = Arrow::Decimal32.new(11)
+    other_decimal2 = Arrow::Decimal32.new(9)
+    assert_equal([
+                   false,
+                   true,
+                   true
+                 ],
+                 [
+                   decimal >= other_decimal1,
+                   decimal >= other_decimal2,
+                   decimal >= decimal
+                 ])
+  end
+
+  def test_rescale
+    decimal = Arrow::Decimal32.new(10)
+    assert_equal(Arrow::Decimal32.new(1000),
+                 decimal.rescale(1, 3))
+  end
+
+  def test_rescale_fail
+    decimal = Arrow::Decimal32.new(10)
+    message =
+      "[decimal32][rescale]: Invalid: " +
+      "Rescaling Decimal32 value would cause data loss"
+    assert_raise(Arrow::Error::Invalid.new(message)) do
+      decimal.rescale(1, -1)
+    end
+  end
+end

Reply via email to