Преобразовать десятичное число в двойное?
-
08-06-2019 - |
Вопрос
Я хочу использовать панель отслеживания, чтобы изменить непрозрачность формы.
Это мой код:
decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;
Когда я создаю приложение, оно выдает следующую ошибку:
Невозможно неявно преобразовать тип
'decimal'
к'double'
.
Я попробовал использовать trans
и double
но тогда управление не работает.Этот код отлично работал в прошлом проекте VB.NET.
Решение
Явное приведение к удвоению не требуется:
double trans = (double) trackBar1.Value / 5000.0;
Определение константы как 5000.0
(или как 5000d
) достаточно:
double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
Другие советы
Более общий ответ на общий вопрос «Десятичный или двойной?»: Десятичная дробь для денежных расчетов, чтобы сохранить точность, Двойной для научных расчетов, на которые не влияют небольшие различия.Поскольку Double — это тип, который является собственным для ЦП (внутреннее представление хранится в база 2), вычисления, выполненные с помощью Double, выполняются лучше, чем Decimal (который представлен в основание 10 внутренне).
Ваш код отлично работал в VB.NET, поскольку он неявно выполняет любые приведения, тогда как в C# есть как неявные, так и явные приведения.
В C# преобразование десятичной дроби в двойную является явным, поскольку вы теряете точность.Например, 1,1 нельзя точно выразить в виде двойного числа, но можно выразить в десятичном виде (см.Числа с плавающей запятой – более неточные, чем вы думаете"по какой причине).
В VB преобразование было добавлено за вас компилятором:
decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;
Что (double)
должно быть явно указано в C#, но может быть подразумеваемый более «щадящим» компилятором VB.
Зачем вы делите на 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;
}
У вас есть две проблемы.Первый, Opacity
требуется двойное, а не десятичное значение.Компилятор сообщает вам, что, хотя существует преобразование между десятичными и двойными числами, это явное преобразование, которое вам нужно указать, чтобы оно работало.Второе заключается в том, что TrackBar.Value
является целочисленным значением, и деление целого числа на целое число приводит к получению целого числа независимо от того, какому типу переменной вы его присвоили.В этом случае происходит неявное приведение от int к десятичному или двойному - потому что при приведении не происходит потери точности - поэтому компилятор не жалуется, но получаемое вами значение всегда предположительно равно 0, поскольку trackBar.Value
всегда меньше 5000.Решение состоит в том, чтобы изменить ваш код, чтобы использовать 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
как целое число, и поскольку trackbar1.Value
также является целым числом trans
значение всегда было нулевым.Явно сделав число значением с плавающей запятой, добавив .0
компилятор теперь может интерпретировать его как двойное и выполнить правильные вычисления.
Лучшее решение:
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
С Opacity
- это двойное значение, я бы просто использовал двойное значение с самого начала и вообще не приводил его, но обязательно используйте двойное значение при делении, чтобы не потерять точность
Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;