Преобразовать десятичную в двойную?
Я хочу использовать трек-бар, чтобы изменить прозрачность формы.
Это мой код:
decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;
Когда я создаю приложение, оно выдает следующую ошибку:
Невозможно неявно преобразовать тип
'decimal'
в'double'
,
Я пытался с помощью trans
а также double
но тогда контроль не работает. Этот код прекрасно работал в прошлом проекте VB.NET.
17 ответов
Явное приведение к удвоению, как это, необязательно:
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 на int приводит к int независимо от того, к какому типу переменных вы его назначаете. В этом случае происходит неявное приведение от int к десятичному или двойному - потому что при выполнении преобразования нет потери точности - поэтому компилятор не жалуется, но полученное вами значение всегда равно 0, предположительно, так как trackBar.Value
всегда меньше 5000. Решение состоит в том, чтобы изменить ваш код на использование double (собственный тип для Opacity) и выполнять арифметику с плавающей запятой, явно делая константу 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
это двойное значение, и компилятору не нравится, когда вы пытаетесь втиснуть в него десятичное значение.
Свойство 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
является целым числом, и он будет выполнять целочисленное деление, а результатом будет целое число.
Предполагая, что вы используете 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
теперь компилятор может интерпретировать его как двойное и выполнить правильный расчет.
Поскольку Opacity
это двойное значение, я бы просто использовал double с самого начала, а не бросал вообще, но обязательно использовал double при делении, чтобы не потерять точность
Opacity = trackBar1.Value / 5000.0;
Лучшее решение:
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
Попробуй это:
Opacity = decimal.ToDouble(trackBar1.Value / 5000.0);```
ОГ Факт:Double
тип представляет более широкий диапазон возможных значений, чемDecimal
.
Кастинг в роли двойника
decimal trans = trackBar1.Value / 5000m;
this.Opacity = (double) trans;
Преобразование типа
decimal trans = trackBar1.Value / 5000m;
this.Opacity = decimal.ToDouble(trans);
Нет явного приведения/преобразования
В этом случае добавление «d» в конце константы5000d
или ".0"5000.0
идентифицирует требуемый тип. Когда в операции нет константы, просто умножьте своюdecimal
переменная по1.0
или1d
.
Попробуй это -
// десятичные значения
decimal d1 = 3234.3434m;
// преобразовать в двойной
double r1 = Decimal.ToDouble(d1);
Мы можем сделать что-то вроде этого:
double trans = trackBar1.Value / 5000.0;
this.Opacity = trans;
Или упрощенно:
this.Opacity = trackBar1.Value / 5000.0;
Вы также можете использовать встроенные функции преобразования, такие как
Decimal.ToDouble()
:
double trans = trackBar1.Value / 5000.0;
this.Opacity = Decimal.ToDouble(trans);
Вы также можете использовать упрощенную форму, но я не предлагаю использовать
ToDouble()
в таком случае.