C# правильное и эффективное преобразование двойного в десятичное

Какой самый эффективный (и строго правильный) способ конвертировать из double к decimal округлено до n места точности?

я использую decimal.Round((decimal)d, n, MidpointRounding.AwayFromZero) но мне приходит в голову, что я здесь дважды скругляю (decimal)d и один раз через Round(),

Есть ли способ, чтобы прямо вокруг double к decimal в n места? Я полагаю, что могу путешествовать туда и обратно через строки, но это кажется уродливым и дорогим.


5/12/2017: я добавил проблему в corefx github здесь https://github.com/dotnet/corefx/issues/19706

3 ответа

Я не понимаю, почему вы хотите округлить двойное значение при преобразовании его в десятичное, так как десятичное число имеет гораздо большую точность, чем двойное. Округление просто не имеет смысла.

Вы можете просто привести двойную к десятичной:

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

или как предложено другими:

decimalValue = Convert.ToDecimal(doubleValue);

И если вы действительно обеспокоены производительностью (и я не совсем уверен, что это так), вам следует переосмыслить использование десятичного числа вместо двойного, так как оно не очень быстрое и не очень эффективное использование памяти. Double достаточно точен для многих приложений, и вам стоит подумать, нужна ли вам дополнительная точность, предоставляемая десятичным типом.

Если ваш двойник имеет 15 значащих цифр, то System.Convert.ToDecimal(d) делает трюк:

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

Таким образом, вы можете достичь желаемого округления без преобразования строки или Decimal.Round(), сначала добавляя подходящую степень 10 (для создания начальных цифр и уменьшения количества десятичных знаков в результате) или вычитая старшие значащие цифры (для увеличения количества десятичных знаков), затем вызывая Convert.ToDecimal(d) (тем самым округляя ваш модифицированный дубль до 15-й значащей цифры) и, наконец, вычитая или добавляя начальные цифры снова из десятичного числа.

Я действительно думаю, что твой путь лучше.

Вы хотите сделать два шага:

  1. Преобразовать в десятичную
  2. Вокруг п мест

Вы не можете уменьшить эти шаги до одного. Даже если бы была функция, которая получает double number унд int places в качестве параметров, он должен сделать эти два шага.

Другие вопросы по тегам