简体   繁体   中英

C# correct and efficient conversion of double to decimal

What is the most efficient (and strictly correct) way to convert from a double to a decimal rounded to n places of precision?

I am using decimal.Round((decimal)d, n, MidpointRounding.AwayFromZero) but it occurs to me that I am rounding twice here- once duing the cast (decimal)d and once via Round() .

Is there a way to directly round a double to a decimal to n places? I suppose I can round trip it via strings but that seems ugly and expensive.


5/12/2017: i added an issue to corefx github here https://github.com/dotnet/corefx/issues/19706

If your double happens to have 15 significant digits, then System.Convert.ToDecimal(d) does the trick:

Console.WriteLine(Convert.ToDecimal(123456789012345500.12D));  // Displays 123456789012346000
Console.WriteLine(Convert.ToDecimal(123456789012346500.12D));  // Displays 123456789012346000

Console.WriteLine(Convert.ToDecimal(10030.12345678905D));      // Displays 10030.123456789 
Console.WriteLine(Convert.ToDecimal(10030.12345678915D));      // Displays 10030.1234567892

Therefore, you can achieve the desired rounding without string conversion or Decimal.Round() , by first adding a suitable power of 10 (to create leading digits and reduce the number of decimals in the result) or subtracting the most significant digits (to increase the number of decimals), then invoking Convert.ToDecimal(d) (thereby rounding your modified Double at the 15th significant digit), and finally subtracting or adding the leading digits again from the Decimal number.

I really think your way is better.

You want to do two steps:

  1. Convert to decimal
  2. Round to n places

You can't reduce these steps to one. Even if there were a function which gets a double number und int places as parameters, it has to do these two steps.

What I don't understand is why do you want to round the double value when you convert it to decimal, since decimal has a lot more precision than double. The rounding simply does not have sense.

You can simply cast the double to decimal:

double doubleValue = 12.23;
decimal decimalValue = (decimal) doubleValue;

or as suggested by the others:

decimalValue = Convert.ToDecimal(doubleValue);

And if you are really concerned about performance (and I am not very sure this is the case) you should rethink about using decimal instead of double, as it is neither very fast, nor very memory efficient. Double is precise enough for many applications and you should really think if you need that additional precision offered by decimal type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM