Вопрос:

Преобразовать десятичную в двойную?

c# floating-point type-conversion double decimal

42136 просмотра

13 ответа

942 Репутация автора

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

Это мой код:

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

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

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

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

Автор: Eggs McLaren Источник Размещён: 31.07.2008 09:42

Ответы (13)


424 плюса

15553 Репутация автора

Решение

Явное приведение к удвоению, как это, необязательно:

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

Идентификация константы как 5000.0(или как 5000d) достаточна:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
Автор: Kevin Dente Размещён: 31.07.2008 10:17

55 плюса

7951 Репутация автора

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

Автор: Ryan Fox Размещён: 01.08.2008 01:53

121 плюса

11421 Репутация автора

Более общий ответ на общий вопрос «Десятичное число против двойного?»: Десятичное для денежных расчетов, чтобы сохранить точность, Двойное для научных вычислений, на которые не влияют небольшие различия. Поскольку Double является типом, который является родным для ЦП (внутреннее представление хранится в базе 2 ), вычисления, выполненные с помощью Double, работают лучше, чем Decimal (который представлен внутри базы 10 ).

Автор: huseyint Размещён: 01.08.2008 02:23

57 плюса

23017 Репутация автора

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

Помимо (или вместо) добавления .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);
Автор: andnil Размещён: 05.08.2008 08:18

80 плюса

98280 Репутация автора

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

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

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

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

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

Автор: Keith Размещён: 10.08.2008 05:54

77 плюса

11237 Репутация автора

Почему ты делишь на 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;
}
Автор: Gordon Bell Размещён: 21.09.2008 03:51

47 плюса

26376 Репутация автора

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

Автор: Dinah Размещён: 20.11.2008 02:36

60 плюса

439417 Репутация автора

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

trackBar.Opacity = (double)trackBar.Value / 5000.0;
Автор: tvanfosson Размещён: 27.02.2009 11:45

45 плюса

868468 Репутация автора

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

Автор: Darin Dimitrov Размещён: 31.08.2011 07:08

45 плюса

117177 Репутация автора

Предполагая, что вы используете 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компилятора теперь можно интерпретировать его как двойное и выполнить надлежащие вычисления.

Автор: ChrisF Размещён: 31.08.2011 07:09

39 плюса

11762 Репутация автора

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

this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
Автор: Danny Fox Размещён: 06.03.2012 08:07

39 плюса

459 Репутация автора

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

Opacity = trackBar1.Value / 5000.0;
Автор: Darryl Размещён: 13.05.2012 02:10

33 плюса

336 Репутация автора

this.Opacity = trackBar1.Value / 5000d;
Автор: eaponz Размещён: 11.04.2013 03:08
32x32