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