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 number
унд int places
в качестве параметров, он должен сделать эти два шага.
Если ваш двойник имеет 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-й значащей цифры) и, наконец, вычитая или добавляя начальные цифры снова из десятичного числа.
Я действительно думаю, что твой путь лучше.
Я не понимаю, почему вы хотите округлить двойное значение при преобразовании его в десятичное, так как десятичное число имеет гораздо большую точность, чем двойное. Округление просто не имеет смысла.
Вы можете просто привести двойную к десятичной:
double doubleValue = 12.23;
decimal decimalValue = (decimal) doubleValue;
или как предложено другими:
decimalValue = Convert.ToDecimal(doubleValue);
И если вы действительно обеспокоены производительностью (и я не совсем уверен, что это так), вам следует переосмыслить использование десятичного числа вместо двойного, так как оно не очень быстрое и не очень эффективное использование памяти. Double достаточно точен для многих приложений, и вам стоит подумать, нужна ли вам дополнительная точность, предоставляемая десятичным типом.