Description
We could improve the BsonDouble type converting values from a float type without losing precision like decimal types (decimal type in C# solves the losing precision converting some numeric values).
Example:
With the actual implementation, the function BsonTypeMapper.MapToBsonValue returns a BsonDouble with precision lost if the parameter passed is a float. See the following new test case:
float value2 = 1.3f;
BsonDouble secondBsonValue = (BsonDouble)BsonTypeMapper.MapToBsonValue(value2);
BsonDouble expectedResult = 1.3d;
Assert.AreSame(expectedResult, secondBsonValue);
The test case result is:
MongoDB.Bson.Tests.BsonTypeMapperTests.TestMapBsonDouble:
Expected: same as <1.3>
But was: <1.2999999523162842>
Also the comparison is not entirely accurate. See the following code of a console test code:
float value = 1.3f;
var bsonValue = (BsonDouble)BsonTypeMapper.MapToBsonValue(value);
bool result1 = (value == bsonValue);
Console.WriteLine("Case 1: Original:
var bsonDouble = (BsonDouble)BsonTypeMapper.MapToBsonValue(value, BsonType.Double);
bool result2 = (value == bsonDouble);
Console.WriteLine("Case 2: Original: {0}
, converted:
{1}. AreSame: {2}. ¿?¿ ", value, bsonDouble, result2);Console.ReadKey();
Outputs:
Case 1: Original: 1,3, converted: 1.2999999523162842. AreSame: True. ¿?¿
Case 2: Original: 1,3, converted: 1.2999999523162842. AreSame: True. ¿?¿
Proposed solution:
Use the decimal type as an intermediate cast.
This code converts values without losing precision.
float f = 3.2f;
double d = (double)(decimal)f;
double d2 = (double)f; // Loss
Console.WriteLine("Original float: {0} and converted double: {1}
", f, d);
Console.WriteLine("Original float:
and converted double without intermediate decimal:
{1}", f, d2);
Output:
Original float: 3,2 and converted double: 3,2
Original float: 3,2 and converted double without intermediate decimal: 3,2000000
4768372
I needed solve it and I have a valid implementation which passes the test cases and I’m able to pull request shortly.