diff --git a/lang/csharp/src/apache/main/AvroDecimal.cs b/lang/csharp/src/apache/main/AvroDecimal.cs index 794617c4979..ed748ae35f0 100644 --- a/lang/csharp/src/apache/main/AvroDecimal.cs +++ b/lang/csharp/src/apache/main/AvroDecimal.cs @@ -1140,20 +1140,14 @@ public int CompareTo(AvroDecimal other) 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 f90b11a324e..c6d0d3a807e 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 @@ public void TestHighPrecisionAvroDecimalToString() 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); + } } }