You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by rs...@apache.org on 2026/05/02 07:50:55 UTC

(avro) branch main updated: AVRO-4162: [csharp] Fix AvroDecimal.CompareTo for values with different scales (#3744)

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

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


The following commit(s) were added to refs/heads/main by this push:
     new 5af5735cec AVRO-4162: [csharp] Fix AvroDecimal.CompareTo for values with different scales (#3744)
5af5735cec is described below

commit 5af5735cec1ed939ad40f4f599e099fd2d2b29e8
Author: ChristophMajcenAtXxxlutz <Ch...@xxxl.digital>
AuthorDate: Sat May 2 09:50:50 2026 +0200

    AVRO-4162: [csharp] Fix AvroDecimal.CompareTo for values with different scales (#3744)
    
    * fix(AVRO-4162): dotnet AvroDecimal.CompareTo for values with different scale
    
    * fix(AVRO-4162): Make tests not culture-sensitive
---
 lang/csharp/src/apache/main/AvroDecimal.cs     | 10 +----
 lang/csharp/src/apache/test/AvroDecimalTest.cs | 56 +++++++++++++++++++-------
 2 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/lang/csharp/src/apache/main/AvroDecimal.cs b/lang/csharp/src/apache/main/AvroDecimal.cs
index 794617c497..ed748ae35f 100644
--- a/lang/csharp/src/apache/main/AvroDecimal.cs
+++ b/lang/csharp/src/apache/main/AvroDecimal.cs
@@ -1140,20 +1140,14 @@ namespace Avro
             var unscaledValueCompare = UnscaledValue.CompareTo(other.UnscaledValue);
             var scaleCompare = Scale.CompareTo(other.Scale);
 
-            // if both are the same value, return the value
-            if (unscaledValueCompare == scaleCompare)
-            {
-                return unscaledValueCompare;
-            }
-
             // if the scales are both the same return unscaled value
             if (scaleCompare == 0)
             {
                 return unscaledValueCompare;
             }
 
-            var scaledValue = BigInteger.Divide(UnscaledValue, BigInteger.Pow(new BigInteger(10), Scale));
-            var otherScaledValue = BigInteger.Divide(other.UnscaledValue, BigInteger.Pow(new BigInteger(10), other.Scale));
+            var scaledValue = (decimal) UnscaledValue / (decimal) Math.Pow(10, Scale);
+            var otherScaledValue = (decimal) other.UnscaledValue / (decimal) Math.Pow(10, other.Scale);
 
             return scaledValue.CompareTo(otherScaledValue);
         }
diff --git a/lang/csharp/src/apache/test/AvroDecimalTest.cs b/lang/csharp/src/apache/test/AvroDecimalTest.cs
index f90b11a324..c6d0d3a807 100644
--- a/lang/csharp/src/apache/test/AvroDecimalTest.cs
+++ b/lang/csharp/src/apache/test/AvroDecimalTest.cs
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+using System.Globalization;
 using NUnit.Framework;
 
 namespace Avro.test
@@ -23,22 +24,24 @@ namespace Avro.test
     [TestFixture]
     class AvroDecimalTest
     {
-        [TestCase(1)]
-        [TestCase(1000)]
-        [TestCase(10.10)]
-        [TestCase(0)]
-        [TestCase(0.1)]
-        [TestCase(0.01)]
-        [TestCase(-1)]
-        [TestCase(-1000)]
-        [TestCase(-10.10)]
-        [TestCase(-0.1)]
-        [TestCase(-0.01)]
-        public void TestAvroDecimalToString(decimal value)
+        //Use strings as parameters as otherwise doubles will be used intermediately by C# and scale will be lost in this process
+        [TestCase("1")]
+        [TestCase("1000")]
+        [TestCase("10.10")]
+        [TestCase("0")]
+        [TestCase("0.1")]
+        [TestCase("0.01")]
+        [TestCase("-1")]
+        [TestCase("-1000")]
+        [TestCase("-10.10")]
+        [TestCase("-0.1")]
+        [TestCase("-0.01")]
+        public void TestAvroDecimalToString(string value)
         {
-            var valueString = value.ToString();
+            var valueDecimal = decimal.Parse(value, CultureInfo.InvariantCulture);
+            var valueString = valueDecimal.ToString();
 
-            var avroDecimal = new AvroDecimal(value);
+            var avroDecimal = new AvroDecimal(valueDecimal);
             var avroDecimalString = avroDecimal.ToString();
 
             Assert.AreEqual(valueString, avroDecimalString);
@@ -63,5 +66,30 @@ namespace Avro.test
 
             Assert.AreEqual(valueString, avroDecimalString);
         }
+
+        //Use strings as parameters as otherwise doubles will be used intermediately by C# and scale will be lost in this process
+        [TestCase("0", "0", ExpectedResult = 0)]
+        [TestCase("1", "0", ExpectedResult = 1)]
+        [TestCase("0", "1", ExpectedResult = -1)]
+        [TestCase("1.0", "1.0", ExpectedResult = 0)]
+        [TestCase("1.0", "1", ExpectedResult = 0)]
+        [TestCase("1", "1.0", ExpectedResult = 0)]
+        [TestCase("1.0", "0", ExpectedResult = 1)]
+        [TestCase("0", "1.0", ExpectedResult = -1)]
+        [TestCase("-0.5", "-1.0", ExpectedResult = 1)]
+        [TestCase("-1.0", "-0.5", ExpectedResult = -1)]
+        [TestCase("0.1", "0.01", ExpectedResult = 1)]
+        [TestCase("0.01", "0.1", ExpectedResult = -1)]
+        [TestCase("-0.1", "-0.01", ExpectedResult = -1)]
+        [TestCase("-0.01", "-0.1", ExpectedResult = 1)]
+        public int TestAvroDecimalCompareTo(string left, string right)
+        {
+            var leftDecimal = decimal.Parse(left, CultureInfo.InvariantCulture);
+            var rightDecimal = decimal.Parse(right, CultureInfo.InvariantCulture);
+            var leftAvroDecimal = new AvroDecimal(leftDecimal);
+            var rightAvroDecimal = new AvroDecimal(rightDecimal);
+
+            return leftAvroDecimal.CompareTo(rightAvroDecimal);
+        }
     }
 }