Перетворити десятковий у подвійний


672

Я хочу використовувати a, Track-Barщоб змінити Formнепрозорість.

Це мій код:

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

Коли я будую додаток, він видає таку помилку:

Неможливо неявно перетворити тип decimalуdouble

Я спробував з допомогою transі , doubleале тоді Controlне працює. Цей код добре працював у минулому проекті VB.NET.


11
Також десяткове число не може представляти настільки велике значення, як подвійне. Десяткові знаки можуть підніматися лише до +/- 7.9228162514264337593543950335E + 28; тоді як подвійний може піднятися до +/- 1.79769313486232E + 308
TraumaPony,


8
Хтось повинен позначити це як дублікат.
Іван

8
@Ivan: Це 4-е запитання, яке задають ТАК колись ...
Ніколас

1
@Nikolas: Дійсно. Простежуємо тут сьогодні.
червня

Відповіді:


447

Явний акторський склад, який doubleподобається цьому, не потрібен:

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

Визначення постійної як 5000.0(або як 5000d) достатньо:

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

123

Більш узагальнена відповідь на загальне запитання "Десяткові проти подвійних?": Десяткові для грошових розрахунків для збереження точності, Подвійна для наукових розрахунків, на які не впливають невеликі відмінності. Оскільки Double - це тип, який є рідним для процесора (внутрішнє представлення зберігається в базі 2 ), обчислення, зроблені з Double, виконуються краще, ніж десятичний (який представлений у базі 10 всередині).


83

Ваш код добре працював у VB.NET, оскільки він неявно виконує будь-які касти, тоді як у C # є неявні та явні.

У C # перетворення від десяткового до подвійного явне, оскільки ви втрачаєте точність. Наприклад, 1.1 не може бути точно виражений як подвійний, але може бути як десятковий (див. " Числа з плаваючою комою - неточніші, ніж ви думаєте " з причини, чому).

У VB перетворення додав для вас компілятор:

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

Це (double)повинно бути явно вказано в C #, але може бути на увазі більш «прощає» компілятор VB в.


80

Чому ви ділите на 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;
}

5
Хіба це не просто пересуне проблему? Замість проблеми з 5000ОП мали б проблеми 100?
jww

62

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

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

58

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

Окрім (або замість) додавання .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);

57

Здається this.Opacity, це подвійне значення, і компілятору не подобається, що ви намагаєтеся втиснути в нього десяткове значення.


50

Непрозорість властивість подвійного типу:

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



47

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



41

Оскільки Opacityце подвійне значення, я би просто використовував подвійний з самого початку і не ставлю взагалі, але обов'язково використовуйте подвійне при діленні, щоб ви не втратили жодної точності

Opacity = trackBar1.Value / 5000.0;


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.