Skip to content

Commit 6d9b44d

Browse files
CSHARP-2582: Decimal128 to decimal conversion loses precision for zero.
1 parent 0696353 commit 6d9b44d

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

src/MongoDB.Bson/ObjectModel/Decimal128.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -716,11 +716,7 @@ public static decimal ToDecimal(Decimal128 d)
716716
{
717717
if (Flags.IsFirstForm(d._highBits))
718718
{
719-
if (Decimal128.IsZero(d))
720-
{
721-
return decimal.Zero;
722-
}
723-
else if (Decimal128.Compare(d, __minDecimalValue) < 0 || Decimal128.Compare(d, __maxDecimalValue) > 0)
719+
if (Decimal128.Compare(d, __minDecimalValue) < 0 || Decimal128.Compare(d, __maxDecimalValue) > 0)
724720
{
725721
throw new OverflowException("Value is too large or too small to be converted to a Decimal.");
726722
}
@@ -830,7 +826,7 @@ public static short ToInt16(Decimal128 d)
830826
ulong value;
831827
if (Decimal128.TryTruncateToUInt64(d, maxNegativeValue, (ulong)short.MaxValue, out value))
832828
{
833-
return Decimal128.IsNegative(d) ? (value == maxNegativeValue ? short.MinValue : (short )(-(short)value)) : (short)value;
829+
return Decimal128.IsNegative(d) ? (value == maxNegativeValue ? short.MinValue : (short)(-(short)value)) : (short)value;
834830
}
835831
else
836832
{

tests/MongoDB.Bson.Tests/ObjectModel/Decimal128Tests.cs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@
1414
*/
1515

1616
using System;
17-
using System.Collections.Generic;
18-
using System.Linq;
19-
using System.Text;
20-
using System.Threading.Tasks;
21-
using MongoDB.Bson;
2217
using FluentAssertions;
2318
using System.Globalization;
2419
using Xunit;
@@ -40,27 +35,30 @@ public void Default_value()
4035
[InlineData("-1.01", "-1.01")]
4136
[InlineData("-1", "-1")]
4237
[InlineData("0", "0")]
38+
[InlineData("0.000", "0.000")]
4339
[InlineData("1", "1")]
4440
[InlineData("1.01", "1.01")]
41+
[InlineData("1.000", "1.000")]
4542
[InlineData("79228162514264337593543950335", "79228162514264337593543950335")]
4643
[InlineData("-79228162514264337593543950335", "-79228162514264337593543950335")]
47-
public void Decimal(string valueString, string s)
44+
public void Decimal(string valueString, string expectedResult)
4845
{
4946
var value = decimal.Parse(valueString, CultureInfo.InvariantCulture);
5047
var subject = new Decimal128(value);
5148

52-
subject.ToString().Should().Be(s);
49+
subject.ToString().Should().Be(expectedResult);
5350
AssertSpecialProperties(subject);
5451

5552
var result = Decimal128.ToDecimal(subject);
56-
result.Should().Be(value);
53+
result.ToString().Should().Be(value.ToString());
5754

5855
result = (decimal)subject;
59-
result.Should().Be(value);
56+
result.ToString().Should().Be(value.ToString());
6057
}
6158

6259
[Theory]
6360
[InlineData("0", "0")]
61+
[InlineData("0.00", "0.00")]
6462
[InlineData("79228162514264337593543950335", "79228162514264337593543950335")]
6563
[InlineData("1E1", "10")]
6664
[InlineData("1E2", "100")]
@@ -76,14 +74,26 @@ public void Decimal(string valueString, string s)
7674
[InlineData("1E-57", "0")]
7775
[InlineData("1E-99", "0")]
7876
[InlineData("1E-6111", "0")]
79-
[InlineData("10000.0000000000000000000000001", "10000")] // see: CSHARP-2001
77+
[InlineData("10000.0000000000000000000000001", "10000.000000000000000000000000")] // see: CSHARP-2001
8078
public void ToDecimal_should_return_expected_result(string valueString, string expectedResultString)
8179
{
8280
var subject = Decimal128.Parse(valueString);
8381
var expectedResult = decimal.Parse(expectedResultString);
8482

8583
var result = Decimal128.ToDecimal(subject);
8684

85+
result.ToString().Should().Be(expectedResult.ToString());
86+
}
87+
88+
[Theory]
89+
[InlineData(0xE000_0000_0000_0000UL, 0)]
90+
[InlineData(0xE000_2000_0000_0000UL, 0)]
91+
public void ToDecimal_should_return_expected_result_for_second_form(ulong highBits, ulong expectedResult)
92+
{
93+
var subject = Decimal128.FromIEEEBits(highBits, 0x0);
94+
95+
var result = Decimal128.ToDecimal(subject);
96+
8797
result.Should().Be(expectedResult);
8898
}
8999

0 commit comments

Comments
 (0)