Преобразовать Decimal в Double?

Я хочу использовать track-bar для изменения непрозрачности формы.

Это мой код:

decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;

когда я создаю приложение, оно дает следующую ошибку:

не удается неявно преобразовать тип 'decimal' to 'double'.

Я попытался с помощью trans и double но тогда управление не работает. Этот код отлично работал в прошлом VB.NET проект.

13 ответов


явный бросок для удвоения, как это не обязательно:

double trans = (double) trackBar1.Value / 5000.0;

определение константы как 5000.0 (или 5000d) является достаточным:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;

более общий ответ на общий вопрос " Decimal vs Double?": Decimal для денежных расчетов, чтобы сохранить точность,двойной для научных расчетов, которые не затрагиваются небольшими различиями. Поскольку Double - это тип, который является родным для CPU (внутреннее представление хранится в база 2), вычисления, сделанные с помощью Double, выполняют лучше, чем Decimal (который представлен в базовый 10 внутренне).


ваш код работал нормально в VB.NET потому что он неявно выполняет любые приведения, в то время как C# имеет как неявные, так и явные.

в C# преобразование из десятичного в двойной явно, поскольку вы теряете точность. Например, 1.1 не может быть точно выражен как double, но может как decimal (см."числа с плавающей запятой-более неточные, чем вы думаете" по той причине, почему).

в VB преобразование было добавлено для вас компилятор:

decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;

Это (double) должно быть явно указано в C#, но может быть подразумевается более "прощающим" компилятором VB.


почему вы делите на 5000? Просто установите минимальное и максимальное значения Трекбара между 0 и 100, а затем разделите значение на 100 для процента непрозрачности. Приведенный ниже пример минимум 20 не позволяет форме стать полностью невидимой:

private void Form1_Load(object sender, System.EventArgs e)
{
    TrackBar1.Minimum = 20;
    TrackBar1.Maximum = 100;

    TrackBar1.LargeChange = 10;
    TrackBar1.SmallChange = 1;
    TrackBar1.TickFrequency = 5;
}

private void TrackBar1_Scroll(object sender, System.EventArgs e)
{
    this.Opacity = TrackBar1.Value / 100;
}

у вас две проблемы. Во-первых, Opacity требуется двойное, а не десятичное значение. Компилятор говорит вам, что, хотя существует преобразование между decimal и double, это явное преобразование, которое вам нужно указать, чтобы оно работало. Во-вторых, это TrackBar.Value является целочисленным значением и деление int на int приводит к int независимо от того, какой тип переменной вы назначаете. В этом случае существует неявное приведение от int к decimal или double-потому что нет потеря точности при выполнении приведения-поэтому компилятор не жалуется, но значение, которое вы получаете, всегда равно 0, предположительно, так как trackBar.Value всегда меньше 5000. Решение состоит в том, чтобы изменить код на использование double (собственный тип для непрозрачности) и выполнить арифметику с плавающей запятой, явно сделав константу double - что будет иметь эффект продвижения арифметики - или литья trackBar.Value удвоить, что будет делать то же самое - или то и другое. О, и тебе не нужно промежуточное звено. переменная, если она не используется в другом месте. Я предполагаю, что компилятор все равно оптимизирует его.

trackBar.Opacity = (double)trackBar.Value / 5000.0;

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

В дополнение к (или вместо) добавить .0 к номеру, вы можете использовать decimal.ToDouble().

вот несколько примеров:

// Example 1
double transperancy = trackBar1.Value/5000;
this.Opacity = decimal.ToDouble(transperancy);

// Example 2 - with inline temp
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);

звучит как this.Opacity является двойным значением, и компилятору не нравится, что вы пытаетесь втиснуть в него десятичное значение.


вы должны использовать 5000.0 вместо 5000.


на прозрачность свойство имеет двойной тип:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

или просто:

this.Opacity = trackBar1.Value / 5000.0;

или:

this.Opacity = trackBar1.Value / 5000d;

обратите внимание, что я использую 5000.0 (или 5000d), чтобы заставить двойное деление, потому что trackBar1.Value является целым числом, и он будет выполнять целочисленное деление, и результат будет целым числом.


предполагая, что вы используете WinForms,Form.Opacity типа double, так что вы должны использовать:

double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;

Если вам не нужно значение в другом месте, проще написать:

this.Opacity = trackBar1.Value / 5000.0;

почему управление не работает, когда вы изменить свой код, чтобы просто быть двойным, потому что:

double trans = trackbar1.Value / 5000;

, которая трактовала 5000 как целое число, так что ваш trans значение всегда ноль. Явным образом делая число плавающей точкой значение путем добавления .0 компилятор теперь может интерпретировать его как double и выполнить правильный расчет.


лучшее решение:

this.Opacity = decimal.ToDouble(trackBar1.Value/5000);

С Opacity является двойным значением, я бы просто использовал double с самого начала и не бросал вообще, но обязательно используйте double при делении, чтобы вы не теряли никакой точности

Opacity = trackBar1.Value / 5000.0;

this.Opacity = trackBar1.Value / 5000d;