Преобразовать десятичное число в двойное?
Я хочу использовать дорожку для изменения непрозрачности формы.
Это мой код:
decimal trans = trackBar1.Value / 5000; this.Opacity = trans;
Когда я создаю приложение, он дает следующую ошибку:
- Сравнение с плавающей точкой
- проблема с плавающей запятой в R?
- Как я могу написать функцию питания самостоятельно?
- Почему (360/24) / 60 = 0 ... в Java
- Какие типы чисел представляются в двоичной с плавающей запятой?
Невозможно неявно преобразовать тип
'decimal'
в'double'
.
Я попытался использовать trans
и double
но затем элемент управления не работает. Этот код отлично работал в прошлом проекте VB.NET.
- Преобразование с двойным преобразованием без научной нотации
- Выдача результата для float в методе, возвращающем результат изменения float
- Почему «f» требуется при объявлении float?
- извлечение мантиссы и экспонента из двойного в c #
- Как преобразовать строку в float?
- Почему GCC не оптимизирует a * a * a * a * a * a to (a * a * a) * (a * a * a)?
- Функции сравнения с плавающей запятой для C #
- C: Как поместить float на интервал [-pi, pi)
Явное приведение к двойному, как это, необязательно:
double trans = (double) trackBar1.Value / 5000.0;
Идентификация константы как 5000.0
(или как 5000d
) достаточно:
double trans = trackBar1.Value / 5000.0; double trans = trackBar1.Value / 5000d;
Более общий ответ на общий вопрос «Десятичное число против двойного?»: Десятичное значение для денежных расчетов для сохранения точности, Двойное для научных расчетов, на которые не влияют небольшие различия. Поскольку Double является типом, который является родным для CPU (внутреннее представление хранится в базе 2 ), вычисления, сделанные с помощью Double, лучше, чем Decimal (который представлен в базе 10 внутри).
Ваш код отлично работал в VB.NET, потому что он неявно выполняет любые нажатия, в то время как C # имеет как неявные, так и явные.
В C # преобразование из десятичного в double является явным, поскольку вы теряете точность. Например, 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
– это двойное значение, и компилятор не любит, когда вы пытаетесь вставить в него десятичное значение.
Вы должны использовать 5000.0
вместо 5000
.
Свойство 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
компилятор теперь может интерпретировать его как double и выполнять правильный расчет.
Лучшее решение:
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
Так как Opacity
– это двойное значение, я бы просто использовал двойное с самого начала и не использовал его вообще, но обязательно разделите его на double, чтобы не потерять точность
Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;