Перекладіть подвійну змінну в десяткову


96

Як хтось кидає doubleна те, decimalщо використовується при розробці валюти. Куди Mйде?

decimal dtot = (decimal)(doubleTotal);

Відповіді:


85

Ви використовуєте лише Mдля числового літералу, коли ви робите це просто:

decimal dtot = (decimal)doubleTotal;

Зверніть увагу, що число з плаваючою комою не підходить для збереження точного значення, тому, якщо спочатку скласти числа, а потім перетворити на них, Decimalви можете отримати помилки округлення. Можливо, вам доведеться перетворити числа в, Decimalперш ніж складати їх разом, або переконайтесь, що ці цифри спочатку не є числами з плаваючою точкою.


як наступне запитання, чому потрібне явне перетворення? Я спробував це, і я отримую помилку про те, що дубль не може бути явно приведений до десяткової, але чи не має десяткова велика точність? (тобто приблизно так само, як кастинг з int на double може бути неявним.)

4
@Cortana: Точність десяткової коми вища, але діапазон менший. Подвійне значення може бути поза діапазоном для десяткової коми. Див: stackoverflow.com/questions/7817866 / ...
Guffa

41

Ви можете перетворити подвійне в десяткове, як це, без необхідності Mбуквального суфікса:

double dbl = 1.2345D;
decimal dec = (decimal) dbl;

Ви повинні використовувати Mпри оголошенні нового буквального десяткового значення:

decimal dec = 123.45M;

(Без M, 123.45 розглядається як подвійний і не компілюється.)


28

використовувати клас перетворення за замовчуванням: Convert.ToDecimal(Double)


1
Ні, оскільки це викличе OverflowException double vol_y = (double) Decimal.MaxValue + 10E + 28D; Console.WriteLine ("Convert.ToDecimal (vol_y) =" + Convert.ToDecimal (vol_y));
ToXinE

2
@ToXinE IMHO в більшості випадків OverflowException кращий за
мовчазне

16
Convert.ToDecimal(the double you are trying to convert);

2
Я дізнався, що клас Convert набагато гнучкіший та безпечніший, ніж відливання в C #.
Том,

3
"Сейф"? як у випадку, коли він не може привести, він видає виняток під час виконання замість помилки компілятора? Мене це вкусило стільки разів, що я активно уникаю перетворення ...
Пітер Річі,

8
Потік @PeterRitchie трохи старий, але це слід сказати: Виклик методу Convert безпосередньо був би найбільш підходящим підходом. Можливо, я просто урод оптимізації, але одна інструкція для вирішення - це бонус (оскільки використання явного синтаксису (Type) - це просто перевантаження оператора, що викликає Convert).
Mike Johnson

2
@PeterRitchie: З точки зору дизайну мови, було б краще вимагати від програміста використання одного з двох методів перетворення, а не дозволяти типову трансляцію з doubleдо decimal, враховуючи, що для такого doubleзначення, як (1000000.0 / 3.0), в деяких випадках хочуть відрізати "надлишкову" точність, що дає 333333.333333333D, але в інших випадках хочеться зберегти її, даючи 333333.333333333313931D. Замість того, щоб просто говорити "перетворити в десяткове число", код повинен визначати, як це перетворення повинно виконуватися.
supercat

2
@supercat, який справді здається не пов'язаним з моїм першим коментарем, оскільки використання Convert.ToDecimal(double)є таким самим (decimal)doubleTotal, за винятком випадків, якщо його doubleTotalзмінили на інший тип, ви, мабуть, уникнете помилки під час компіляції та внесете важче знайти помилку під час виконання, оскільки інший ToDecimal перевизначення може викликатися. Оператор акторського складу набагато чіткіший ...
Пітер Річі,

1

Ну, це старе запитання, і я справді використав деякі відповіді, показані тут. Тим не менш, у моєму конкретному сценарії було можливо, що doubleвартість, яку я хотів перетворити, decimalчасто була більшою, ніж decimal.MaxValue. Отже, замість обробки винятків я написав цей метод розширення:

    public static decimal ToDecimal(this double @double) => 
        @double > (double) decimal.MaxValue ? decimal.MaxValue : (decimal) @double;

Вищезазначений підхід працює, якщо ви не хочете турбуватись обробкою винятків із переповнення, і якщо таке трапляється, ви просто хочете зберегти максимально можливе значення (мій випадок), але я знаю, що для багатьох інших сценаріїв це не буде очікуваною поведінкою і може бути необхідна обробка винятків.


1
Це не вдалося б у наступному випадку double _double = (double) decimal.MaxValue; Я б запропонував використовувати> = у порівнянні загальнодоступного статичного десяткового ToDecimal (цей подвійний _double) => _double> = (подвійний) decimal.MaxValue? decimal.MaxValue: (десятковий) _double;
Martin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.