Сведения о вопросе

LARVION

16:03, 1st July, 2020

Теги

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

Просмотров: 670   Ответов: 13

Я хочу использовать трек-бар, чтобы изменить непрозрачность формы.

Это мой код:

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

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

Невозможно неявно преобразовать тип 'decimal' в 'double' .

Я пробовал использовать trans и double , но тогда контроль не работает. Этот код прекрасно работал в прошлом проекте VB.NET.



  Сведения об ответе

crush

18:03, 1st July, 2020

Явный бросок для удвоения вроде этого не нужен:

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

Достаточно определить константу как 5000.0 (или как 5000d ).:

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


  Сведения об ответе

fo_I_K

18:03, 1st July, 2020

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


  Сведения об ответе

SSESION

18:03, 1st July, 2020

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

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

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

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

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


  Сведения об ответе

FAriza

18:03, 1st July, 2020

Почему вы делите на 5000? Просто установите минимальное и максимальное значения TrackBar между 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;
}


  Сведения об ответе

prince

18:03, 1st July, 2020

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

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


  Сведения об ответе

PROGA

18:03, 1st July, 2020

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

В дополнение к (или вместо) добавления .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);


  Сведения об ответе

P_S_S

18:03, 1st July, 2020

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


  Сведения об ответе

LAST

18:03, 1st July, 2020

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


  Сведения об ответе

dump

18:03, 1st July, 2020

Свойство Opacity имеет двойной тип:

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 -это целое число, и оно будет выполнять целочисленное деление, и результат будет целым числом.


  Сведения об ответе

DO__IT

18:03, 1st July, 2020

Предполагая, что вы используете 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 как целое число, и поскольку trackbar1.Value также является целым числом, ваше значение trans всегда было равно нулю. Явным образом сделав числовое значение значением с плавающей запятой, добавив .0 , компилятор теперь может интерпретировать его как двойник и выполнить правильное вычисление.


  Сведения об ответе

qwerty101

18:03, 1st July, 2020

Самое лучшее решение-это:

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


  Сведения об ответе

JUST___

18:03, 1st July, 2020

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

Opacity = trackBar1.Value / 5000.0;


  Сведения об ответе

PROGA

18:03, 1st July, 2020

this.Opacity = trackBar1.Value / 5000d;


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться