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 567f9c596e GH-44588: [GLib] Add GArrowDecimal64 Class (#44591)
567f9c596e is described below
commit 567f9c596ed8e5b9c4435172442997874a4764e0
Author: Hiroyuki Sato <[email protected]>
AuthorDate: Thu Oct 31 15:53:39 2024 +0900
GH-44588: [GLib] Add GArrowDecimal64 Class (#44591)
### Rationale for this change
`Decimal64` class has been introeduced. It is necessary to support in GLib.
### What changes are included in this PR?
Implement `GArrowDecimal64` class.
### Are these changes tested?
YES
### Are there any user-facing changes?
NO
* GitHub Issue: #44588
Lead-authored-by: Hiroyuki Sato <[email protected]>
Co-authored-by: Sutou Kouhei <[email protected]>
Signed-off-by: Sutou Kouhei <[email protected]>
---
c_glib/arrow-glib/decimal.cpp | 435 +++++++++++++++++++++++++++++++++++++++++-
c_glib/arrow-glib/decimal.h | 79 ++++++++
c_glib/arrow-glib/decimal.hpp | 5 +
c_glib/test/test-decimal64.rb | 222 +++++++++++++++++++++
4 files changed, 740 insertions(+), 1 deletion(-)
diff --git a/c_glib/arrow-glib/decimal.cpp b/c_glib/arrow-glib/decimal.cpp
index 5947868edd..edc2af7a7e 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::Decimal64>
+{
+ using ArrowType = arrow::Decimal64;
+ using GArrowType = GArrowDecimal64;
+
+ GArrowType *
+ new_raw(std::shared_ptr<ArrowType> *arrow_decimal64)
+ {
+ return garrow_decimal64_new_raw(arrow_decimal64);
+ }
+
+ std::shared_ptr<ArrowType>
+ get_raw(GArrowType *decimal64)
+ {
+ return garrow_decimal64_get_raw(decimal64);
+ }
+};
+
template <> struct DecimalConverter<arrow::Decimal128>
{
using ArrowType = arrow::Decimal128;
@@ -301,9 +319,11 @@ G_BEGIN_DECLS
/**
* SECTION: decimal
* @section_id: decimal
- * @title: 128-bit and 256-bit decimal classes
+ * @title: 64-bit, 128-bit and 256-bit decimal classes
* @include: arrow-glib/arrow-glib.h
*
+ * #GArrowDecimal64 is a 64-bit decimal class.
+ *
* #GArrowDecimal128 is a 128-bit decimal class.
*
* #GArrowDecimal256 is a 256-bit decimal class.
@@ -311,6 +331,404 @@ G_BEGIN_DECLS
* Since: 0.10.0
*/
+typedef struct GArrowDecimal64Private_
+{
+ std::shared_ptr<arrow::Decimal64> decimal64;
+} GArrowDecimal64Private;
+
+enum {
+ PROP_DECIMAL64 = 1
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE(GArrowDecimal64, garrow_decimal64, G_TYPE_OBJECT)
+
+#define GARROW_DECIMAL64_GET_PRIVATE(obj)
\
+ static_cast<GArrowDecimal64Private *>(
\
+ garrow_decimal64_get_instance_private(GARROW_DECIMAL64(obj)))
+
+static void
+garrow_decimal64_finalize(GObject *object)
+{
+ auto priv = GARROW_DECIMAL64_GET_PRIVATE(object);
+
+ priv->decimal64.~shared_ptr();
+
+ G_OBJECT_CLASS(garrow_decimal64_parent_class)->finalize(object);
+}
+
+static void
+garrow_decimal64_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ auto priv = GARROW_DECIMAL64_GET_PRIVATE(object);
+
+ switch (prop_id) {
+ case PROP_DECIMAL64:
+ priv->decimal64 =
+ *static_cast<std::shared_ptr<arrow::Decimal64>
*>(g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+garrow_decimal64_init(GArrowDecimal64 *object)
+{
+ auto priv = GARROW_DECIMAL64_GET_PRIVATE(object);
+ new (&priv->decimal64) std::shared_ptr<arrow::Decimal64>;
+}
+
+static void
+garrow_decimal64_class_init(GArrowDecimal64Class *klass)
+{
+ auto gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->finalize = garrow_decimal64_finalize;
+ gobject_class->set_property = garrow_decimal64_set_property;
+
+ GParamSpec *spec;
+ spec = g_param_spec_pointer(
+ "decimal64",
+ "Decimal64",
+ "The raw std::shared<arrow::Decimal64> *",
+ static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property(gobject_class, PROP_DECIMAL64, spec);
+}
+
+/**
+ * garrow_decimal64_new_string:
+ * @data: The data of the decimal.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: (nullable):
+ * A newly created #GArrowDecimal64 on success, %NULL on error.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal64 *
+garrow_decimal64_new_string(const gchar *data, GError **error)
+{
+ return garrow_decimal_new_string<arrow::Decimal64>(data,
+ error,
+
"[decimal64][new][string]");
+}
+
+/**
+ * garrow_decimal64_new_integer:
+ * @data: The data of the decimal.
+ *
+ * Returns: A newly created #GArrowDecimal64.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal64 *
+garrow_decimal64_new_integer(const gint64 data)
+{
+ return garrow_decimal_new_integer<arrow::Decimal64>(data);
+}
+
+/**
+ * garrow_decimal64_copy:
+ * @decimal: The decimal to be copied.
+ *
+ * Returns: (transfer full): A copied #GArrowDecimal64.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal64 *
+garrow_decimal64_copy(GArrowDecimal64 *decimal)
+{
+ return garrow_decimal_copy<arrow::Decimal64>(decimal);
+}
+
+/**
+ * garrow_decimal64_equal:
+ * @decimal: A #GArrowDecimal64.
+ * @other_decimal: A #GArrowDecimal64 to be compared.
+ *
+ * Returns: %TRUE if the decimal is equal to the other decimal, %FALSE
+ * otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal64_equal(GArrowDecimal64 *decimal, GArrowDecimal64
*other_decimal)
+{
+ return garrow_decimal_equal<arrow::Decimal64>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal64_not_equal:
+ * @decimal: A #GArrowDecimal64.
+ * @other_decimal: A #GArrowDecimal64 to be compared.
+ *
+ * Returns: %TRUE if the decimal isn't equal to the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal64_not_equal(GArrowDecimal64 *decimal, GArrowDecimal64
*other_decimal)
+{
+ return garrow_decimal_not_equal<arrow::Decimal64>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal64_less_than:
+ * @decimal: A #GArrowDecimal64.
+ * @other_decimal: A #GArrowDecimal64 to be compared.
+ *
+ * Returns: %TRUE if the decimal is less than the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal64_less_than(GArrowDecimal64 *decimal, GArrowDecimal64
*other_decimal)
+{
+ return garrow_decimal_less_than<arrow::Decimal64>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal64_less_than_or_equal:
+ * @decimal: A #GArrowDecimal64.
+ * @other_decimal: A #GArrowDecimal64 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_decimal64_less_than_or_equal(GArrowDecimal64 *decimal,
+ GArrowDecimal64 *other_decimal)
+{
+ return garrow_decimal_less_than_or_equal<arrow::Decimal64>(decimal,
other_decimal);
+}
+
+/**
+ * garrow_decimal64_greater_than:
+ * @decimal: A #GArrowDecimal64.
+ * @other_decimal: A #GArrowDecimal64 to be compared.
+ *
+ * Returns: %TRUE if the decimal is greater than the other decimal,
+ * %FALSE otherwise.
+ *
+ * Since: 19.0.0
+ */
+gboolean
+garrow_decimal64_greater_than(GArrowDecimal64 *decimal, GArrowDecimal64
*other_decimal)
+{
+ return garrow_decimal_greater_than<arrow::Decimal64>(decimal, other_decimal);
+}
+
+/**
+ * garrow_decimal64_greater_than_or_equal:
+ * @decimal: A #GArrowDecimal64.
+ * @other_decimal: A #GArrowDecimal64 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_decimal64_greater_than_or_equal(GArrowDecimal64 *decimal,
+ GArrowDecimal64 *other_decimal)
+{
+ return garrow_decimal_greater_than_or_equal<arrow::Decimal64>(decimal,
other_decimal);
+}
+
+/**
+ * garrow_decimal64_to_string_scale:
+ * @decimal: A #GArrowDecimal64.
+ * @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_decimal64_to_string_scale(GArrowDecimal64 *decimal, gint32 scale)
+{
+ return garrow_decimal_to_string_scale<arrow::Decimal64>(decimal, scale);
+}
+
+/**
+ * garrow_decimal64_to_string:
+ * @decimal: A #GArrowDecimal64.
+ *
+ * Returns: The string representation of the decimal.
+ *
+ * It should be freed with g_free() when no longer needed.
+ *
+ * Since: 19.0.0
+ */
+gchar *
+garrow_decimal64_to_string(GArrowDecimal64 *decimal)
+{
+ return garrow_decimal_to_string<arrow::Decimal64>(decimal);
+}
+
+/**
+ * garrow_decimal64_to_bytes:
+ * @decimal: A #GArrowDecimal64.
+ *
+ * Returns: (transfer full): The binary representation of the decimal.
+ *
+ * Since: 19.0.0
+ */
+GBytes *
+garrow_decimal64_to_bytes(GArrowDecimal64 *decimal)
+{
+ return garrow_decimal_to_bytes<arrow::Decimal64>(decimal);
+}
+
+/**
+ * garrow_decimal64_abs:
+ * @decimal: A #GArrowDecimal64.
+ *
+ * Computes the absolute value of the @decimal destructively.
+ *
+ * Since: 19.0.0
+ */
+void
+garrow_decimal64_abs(GArrowDecimal64 *decimal)
+{
+ garrow_decimal_abs<arrow::Decimal64>(decimal);
+}
+
+/**
+ * garrow_decimal64_negate:
+ * @decimal: A #GArrowDecimal64.
+ *
+ * Negate the current value of the @decimal destructively.
+ *
+ * Since: 19.0.0
+ */
+void
+garrow_decimal64_negate(GArrowDecimal64 *decimal)
+{
+ garrow_decimal_negate<arrow::Decimal64>(decimal);
+}
+
+/**
+ * garrow_decimal64_to_integer:
+ * @decimal: A #GArrowDecimal64.
+ *
+ * Returns: The 64-bit integer representation of the decimal.
+ *
+ * Since: 19.0.0
+ */
+gint64
+garrow_decimal64_to_integer(GArrowDecimal64 *decimal)
+{
+ auto arrow_decimal = garrow_decimal64_get_raw(decimal);
+ return static_cast<int64_t>(*arrow_decimal);
+}
+
+/**
+ * garrow_decimal64_plus:
+ * @left: A #GArrowDecimal64.
+ * @right: A #GArrowDecimal64.
+ *
+ * Returns: (transfer full): The added value of these decimals.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal64 *
+garrow_decimal64_plus(GArrowDecimal64 *left, GArrowDecimal64 *right)
+{
+ return garrow_decimal_plus<arrow::Decimal64>(left, right);
+}
+
+/**
+ * garrow_decimal64_minus:
+ * @left: A #GArrowDecimal64.
+ * @right: A #GArrowDecimal64.
+ *
+ * Returns: (transfer full): The subtracted value of these decimals.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal64 *
+garrow_decimal64_minus(GArrowDecimal64 *left, GArrowDecimal64 *right)
+{
+ return garrow_decimal_minus<arrow::Decimal64>(left, right);
+}
+
+/**
+ * garrow_decimal64_multiply:
+ * @left: A #GArrowDecimal64.
+ * @right: A #GArrowDecimal64.
+ *
+ * Returns: (transfer full): The multiplied value of these decimals.
+ *
+ * Since: 19.0.0
+ */
+GArrowDecimal64 *
+garrow_decimal64_multiply(GArrowDecimal64 *left, GArrowDecimal64 *right)
+{
+ return garrow_decimal_multiply<arrow::Decimal64>(left, right);
+}
+
+/**
+ * garrow_decimal64_divide:
+ * @left: A #GArrowDecimal64.
+ * @right: A #GArrowDecimal64.
+ * @remainder: (out) (nullable): A return location for the remainder
+ * value of these decimals. The returned #GArrowDecimal64 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
+ */
+GArrowDecimal64 *
+garrow_decimal64_divide(GArrowDecimal64 *left,
+ GArrowDecimal64 *right,
+ GArrowDecimal64 **remainder,
+ GError **error)
+{
+ return garrow_decimal_divide<arrow::Decimal64>(left,
+ right,
+ remainder,
+ error,
+ "[decimal64][divide]");
+}
+
+/**
+ * garrow_decimal64_rescale:
+ * @decimal: A #GArrowDecimal64.
+ * @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
+ */
+GArrowDecimal64 *
+garrow_decimal64_rescale(GArrowDecimal64 *decimal,
+ gint32 original_scale,
+ gint32 new_scale,
+ GError **error)
+{
+ return garrow_decimal_rescale<arrow::Decimal64>(decimal,
+ original_scale,
+ new_scale,
+ error,
+ "[decimal64][rescale]");
+}
+
typedef struct GArrowDecimal128Private_
{
std::shared_ptr<arrow::Decimal128> decimal128;
@@ -1081,6 +1499,21 @@ garrow_decimal256_rescale(GArrowDecimal256 *decimal,
G_END_DECLS
+GArrowDecimal64 *
+garrow_decimal64_new_raw(std::shared_ptr<arrow::Decimal64> *arrow_decimal64)
+{
+ auto decimal64 =
+ g_object_new(garrow_decimal64_get_type(), "decimal64", arrow_decimal64,
NULL);
+ return GARROW_DECIMAL64(decimal64);
+}
+
+std::shared_ptr<arrow::Decimal64>
+garrow_decimal64_get_raw(GArrowDecimal64 *decimal64)
+{
+ auto priv = GARROW_DECIMAL64_GET_PRIVATE(decimal64);
+ return priv->decimal64;
+}
+
GArrowDecimal128 *
garrow_decimal128_new_raw(std::shared_ptr<arrow::Decimal128> *arrow_decimal128)
{
diff --git a/c_glib/arrow-glib/decimal.h b/c_glib/arrow-glib/decimal.h
index f64afa800a..bb266424b4 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_DECIMAL64 in GArrowType. */
+/* #define GARROW_TYPE_DECIMAL64 (garrow_decimal64_get_type()) */
+GARROW_AVAILABLE_IN_ALL
+G_DECLARE_DERIVABLE_TYPE(GArrowDecimal64, garrow_decimal64, GARROW, DECIMAL64,
GObject)
+
+struct _GArrowDecimal64Class
+{
+ GObjectClass parent_class;
+};
+
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal64 *
+garrow_decimal64_new_string(const gchar *data, GError **error);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal64 *
+garrow_decimal64_new_integer(const gint64 data);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal64 *
+garrow_decimal64_copy(GArrowDecimal64 *decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal64_equal(GArrowDecimal64 *decimal, GArrowDecimal64
*other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal64_not_equal(GArrowDecimal64 *decimal, GArrowDecimal64
*other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal64_less_than(GArrowDecimal64 *decimal, GArrowDecimal64
*other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal64_less_than_or_equal(GArrowDecimal64 *decimal,
+ GArrowDecimal64 *other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal64_greater_than(GArrowDecimal64 *decimal, GArrowDecimal64
*other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gboolean
+garrow_decimal64_greater_than_or_equal(GArrowDecimal64 *decimal,
+ GArrowDecimal64 *other_decimal);
+GARROW_AVAILABLE_IN_19_0
+gchar *
+garrow_decimal64_to_string_scale(GArrowDecimal64 *decimal, gint32 scale);
+GARROW_AVAILABLE_IN_19_0
+gchar *
+garrow_decimal64_to_string(GArrowDecimal64 *decimal);
+GARROW_AVAILABLE_IN_19_0
+GBytes *
+garrow_decimal64_to_bytes(GArrowDecimal64 *decimal);
+GARROW_AVAILABLE_IN_19_0
+void
+garrow_decimal64_abs(GArrowDecimal64 *decimal);
+GARROW_AVAILABLE_IN_19_0
+void
+garrow_decimal64_negate(GArrowDecimal64 *decimal);
+GARROW_AVAILABLE_IN_19_0
+gint64
+garrow_decimal64_to_integer(GArrowDecimal64 *decimal);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal64 *
+garrow_decimal64_plus(GArrowDecimal64 *left, GArrowDecimal64 *right);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal64 *
+garrow_decimal64_minus(GArrowDecimal64 *left, GArrowDecimal64 *right);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal64 *
+garrow_decimal64_multiply(GArrowDecimal64 *left, GArrowDecimal64 *right);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal64 *
+garrow_decimal64_divide(GArrowDecimal64 *left,
+ GArrowDecimal64 *right,
+ GArrowDecimal64 **remainder,
+ GError **error);
+GARROW_AVAILABLE_IN_19_0
+GArrowDecimal64 *
+garrow_decimal64_rescale(GArrowDecimal64 *decimal,
+ gint32 original_scale,
+ gint32 new_scale,
+ GError **error);
+
/* Disabled because it conflicts with GARROW_TYPE_DECIMAL128 in GArrowType. */
/* #define GARROW_TYPE_DECIMAL128 (garrow_decimal128_get_type()) */
GARROW_AVAILABLE_IN_ALL
diff --git a/c_glib/arrow-glib/decimal.hpp b/c_glib/arrow-glib/decimal.hpp
index 054a91b836..dbfb7f30c6 100644
--- a/c_glib/arrow-glib/decimal.hpp
+++ b/c_glib/arrow-glib/decimal.hpp
@@ -25,6 +25,11 @@
#include <arrow-glib/decimal.h>
+GArrowDecimal64 *
+garrow_decimal64_new_raw(std::shared_ptr<arrow::Decimal64> *arrow_decimal64);
+std::shared_ptr<arrow::Decimal64>
+garrow_decimal64_get_raw(GArrowDecimal64 *decimal);
+
GArrowDecimal128 *
garrow_decimal128_new_raw(std::shared_ptr<arrow::Decimal128>
*arrow_decimal128);
std::shared_ptr<arrow::Decimal128>
diff --git a/c_glib/test/test-decimal64.rb b/c_glib/test/test-decimal64.rb
new file mode 100644
index 0000000000..add4f3e0b4
--- /dev/null
+++ b/c_glib/test/test-decimal64.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 TestDecimal64 < Test::Unit::TestCase
+ def test_new_string_invalid
+ message =
+ "[decimal64][new][string]: Invalid: " +
+ "The string '1,1' is not a valid decimal64 number"
+ error = assert_raise(Arrow::Error::Invalid) do
+ Arrow::Decimal64.new("1,1")
+ end
+ assert_equal(message,
+ error.message.lines.first.chomp)
+ end
+
+ def test_copy
+ decimal = Arrow::Decimal64.new("234.23445")
+ assert_equal(decimal, decimal.copy)
+ end
+
+ def test_to_string_scale
+ integer_data = 23423445
+ string_data = "234.23445"
+ decimal = Arrow::Decimal64.new(integer_data)
+ assert_equal(string_data, decimal.to_string_scale(5))
+ end
+
+ def test_to_string
+ string_data = "999999999999999999"
+ decimal = Arrow::Decimal64.new(string_data)
+ assert_equal(string_data, decimal.to_s)
+ end
+
+ def test_to_bytes
+ decimal = Arrow::Decimal64.new("12.3")
+ assert_equal([123].pack("q*"),
+ decimal.to_bytes.to_s)
+ end
+
+ def test_abs
+ absolute_value = "230492239423435324"
+ negative_value = "-230492239423435324"
+ decimal = Arrow::Decimal64.new(negative_value)
+ decimal.abs
+ assert_equal(absolute_value, decimal.to_s)
+ end
+
+ def test_negate
+ positive_value = "230492239423435324"
+ negative_value = "-230492239423435324"
+ decimal = Arrow::Decimal64.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::Decimal64.new(integer_data1)
+ decimal2 = Arrow::Decimal64.new(integer_data2)
+ decimal3 = decimal1.plus(decimal2)
+ assert_equal((integer_data1 + integer_data2).to_s,
+ decimal3.to_s)
+ end
+
+ def test_multiply
+ integer_data1 = 23423445
+ integer_data2 = 5443
+ decimal1 = Arrow::Decimal64.new(integer_data1)
+ decimal2 = Arrow::Decimal64.new(integer_data2)
+ decimal3 = decimal1.multiply(decimal2)
+ assert_equal((integer_data1 * integer_data2).to_s,
+ decimal3.to_s)
+ end
+
+ def test_divide
+ integer_data1 = 23423445
+ integer_data2 = -5443
+ decimal1 = Arrow::Decimal64.new(integer_data1)
+ decimal2 = Arrow::Decimal64.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::Decimal64.new(23423445)
+ decimal2 = Arrow::Decimal64.new(0)
+ message =
+ "[decimal64][divide]: Invalid: Division by 0 in Decimal64"
+ assert_raise(Arrow::Error::Invalid.new(message)) do
+ decimal1.divide(decimal2)
+ end
+ end
+
+ def test_equal
+ decimal = Arrow::Decimal64.new(10)
+ other_decimal1 = Arrow::Decimal64.new(10)
+ other_decimal2 = Arrow::Decimal64.new(11)
+ assert_equal([
+ true,
+ false,
+ ],
+ [
+ decimal == other_decimal1,
+ decimal == other_decimal2,
+ ])
+ end
+
+ def test_not_equal
+ decimal = Arrow::Decimal64.new(10)
+ other_decimal1 = Arrow::Decimal64.new(10)
+ other_decimal2 = Arrow::Decimal64.new(11)
+ assert_equal([
+ false,
+ true,
+ ],
+ [
+ decimal != other_decimal1,
+ decimal != other_decimal2,
+ ])
+ end
+
+ def test_less_than
+ decimal = Arrow::Decimal64.new(10)
+ other_decimal1 = Arrow::Decimal64.new(11)
+ other_decimal2 = Arrow::Decimal64.new(9)
+ assert_equal([
+ true,
+ false,
+ false
+ ],
+ [
+ decimal < other_decimal1,
+ decimal < other_decimal2,
+ decimal < decimal,
+ ])
+ end
+
+ def test_less_than_or_equal
+ decimal = Arrow::Decimal64.new(10)
+ other_decimal1 = Arrow::Decimal64.new(11)
+ other_decimal2 = Arrow::Decimal64.new(9)
+ assert_equal([
+ true,
+ false,
+ true
+ ],
+ [
+ decimal <= other_decimal1,
+ decimal <= other_decimal2,
+ decimal <= decimal
+ ])
+ end
+
+ def test_greater_than
+ decimal = Arrow::Decimal64.new(10)
+ other_decimal1 = Arrow::Decimal64.new(11)
+ other_decimal2 = Arrow::Decimal64.new(9)
+ assert_equal([
+ false,
+ true,
+ false
+ ],
+ [
+ decimal > other_decimal1,
+ decimal > other_decimal2,
+ decimal > decimal
+ ])
+ end
+
+ def test_greater_than_or_equal
+ decimal = Arrow::Decimal64.new(10)
+ other_decimal1 = Arrow::Decimal64.new(11)
+ other_decimal2 = Arrow::Decimal64.new(9)
+ assert_equal([
+ false,
+ true,
+ true
+ ],
+ [
+ decimal >= other_decimal1,
+ decimal >= other_decimal2,
+ decimal >= decimal
+ ])
+ end
+
+ def test_rescale
+ decimal = Arrow::Decimal64.new(10)
+ assert_equal(Arrow::Decimal64.new(1000),
+ decimal.rescale(1, 3))
+ end
+
+ def test_rescale_fail
+ decimal = Arrow::Decimal64.new(10)
+ message =
+ "[decimal64][rescale]: Invalid: " +
+ "Rescaling Decimal64 value would cause data loss"
+ assert_raise(Arrow::Error::Invalid.new(message)) do
+ decimal.rescale(1, -1)
+ end
+ end
+end