Подтвердить что ты не робот

Лучше ли использовать двойную цифру как десятичную или построить "новый" десятичный знак из двойника?

При переходе от двойного к десятичному, предполагая, что мой double может быть представлен как decimal...

Уместнее ли использовать двойное число как десятичное:
(Явная таблица числовых преобразований) (Обратите внимание, что эта запись ошибочно противоречит первому!)

double foo = bar;
decimal foobar = (decimal)foo;

Или более целесообразно называть конструктор decimal:
(Десятичный конструктор)

double foo = bar;
decimal foobar = new decimal(foo);

Я склонен использовать конструктор decimal, но я удивляюсь, почему он использует один и тот же.

Из того, что я могу сказать, единственное различие заключается в том, что явный листинг двойника ниже Decimal.MinValue возвращает ноль, а при использовании конструктора выбрасывается OverflowException

EDIT: @Joren в комментариях ниже отмечает, что бросок бросает OverflowException для небольших значений... так что, по-видимому, документация MSDN неверна.

Вопросы, относящиеся:
- С# перевести двойную переменную в десятичную - Автоматически отбрасывать с двойного на десятичный: безопасно ли следующее:

4b9b3361

Ответ 1

Там действительно нет разницы. Использование ILSpy:

// decimal
public static explicit operator decimal(double value)
{
    return new decimal(value);
}

Исходя из изучения IL с LINQPad, перегрузка оператора вызывается таким же образом в проверенных и непроверенных контекстах на С#.

В Visual Basic CDec ([double]) и CType ([double], Decimal) вызывает конструктор напрямую, поэтому нет никакой разницы в этом отношении, но литье более способно участвовать во временном сгибании времени компиляции чем конструктор.

Ответ 2

Я бы лучше пошел за конструктором! По крайней мере, вы узнаете, что ваше значение вне пределов, вместо того, чтобы устанавливать его на 0 молча! В документации указано:

Явное числовое преобразование может привести к потере точности или результату в метании исключений.

Если вам не нужна точность, отличная от литья, можно использовать. С другой стороны, если вы играете с деньгами, например, последнее, что вы делаете, это округление вдвое! Вы не хотите, чтобы ваше приложение превращало ценные десятичные дроби в 0, если вы этого не ожидаете.

Ответ 3

Изменить: см. комментарий Джорана на главный пост. Это все равно вызовет исключение здесь, в LINQPad 4 (С# 4/.NET4), даже если unchecked.


Другой вариант - использовать checked (при условии, что в контексте unchecked):

double d = double.MaxValue;
decimal f = checked((decimal)d);

Результат:

OverflowException: значение было слишком большим или слишком маленьким для десятичного числа.

В конце дня, однако, я думаю, что этот вопрос "не является реальным вопросом" в том, что используемый подход зависит не в основном от [ожидаемых] входов, а скорее от того, что должно произойти при переполнении.

Счастливое кодирование.

Ответ 4

Я бы использовал конструктор, потому что это преобразование потенциально может привести к неожиданным результатам из-за разницы в точности. Кажется логичным, что конструктор более подготовлен к обработке преобразования.

Как отмечено в вашем вопросе, есть некоторые обстоятельства, при которых преобразование из double в decimal приведет к OverflowException, что может потребовать некоторой специальной обработки в вашем коде. Кастинг игнорирует это исключение, что может быть нежелательно, если точность критическая.

http://msdn.microsoft.com/en-us/library/9sc2bx9h.aspx

Ответ 5

Мог бы попробовать следующее:

double v = 2.33;
decimal b;

if (decimal.TryParse(v.ToString(), out b))
    //do this
else
    //do that