Как преобразовать десятичную дробь в двойную в C#?

Я хочу использовать Track-Bar для изменения непрозрачности Form.

Это мой код:

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

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

Cannot implicitly convert type decimal to double

Я пробовал использовать trans и double, но тогда Control не работает. Этот код отлично работал в прошлом проекте VB.NET.

Кроме того, Decimal не может представлять такое же широкое значение, как Double. Десятичное число может увеличиваться только до +/- 7,9228162514264337593543950335E + 28; в то время как Double может подняться до +/- 1,79769313486232E + 308

TraumaPony 21.09.2008 08:09

Совершенно не по теме, но это первый вопрос о Stackoverflow, доступный для просмотра пользователям все. (Фактический первый может быть просмотрен пользователями с количеством представителей> 10 тыс.)

expressjs123 01.01.2021 19:10

@TraumaPony, это trackbar. Вряд ли когда-либо делалось использовать такое высокое значение на trackbar.

Franck 24.02.2021 16:07

Ух ты! Это первый вопрос, который еще не решен!

Anonymous 12.03.2021 03:20
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
710
4
55 870
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Ответ принят как подходящий

Явное приведение к double не требуется:

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

Достаточно указать константу как 5000.0 (или как 5000d):

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

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

Более общий ответ на общий вопрос «Десятичное или двойное?»:

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

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

В дополнение к (или вместо) добавления .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);

Ваш код отлично работал в 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;
}

Разве это не решило бы проблему? Вместо проблемы с 5000, у OP будет проблема с 100?

jww 23.09.2014 01:17

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

У вас две проблемы.

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

Во-вторых, TrackBar.Value - это целочисленное значение, и деление int на int приводит к int независимо от того, какой тип переменной вы его назначаете. В этом случае происходит неявное приведение типа int к decimal или double, потому что при приведении нет потери точности. Так что компилятор не жалуется. Но значение, которое вы получаете, по-видимому, всегда равно 0, поскольку trackBar.Value всегда меньше 5000.

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

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

Свойство Непрозрачность имеет двойной тип:

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;

Попробуйте использовать функцию приведения:

this.Opacity = decimal.ToDouble(trackBar1.Value / 5000.0);

Объяснение было бы порядком. Например, в чем идея / суть?

Peter Mortensen 12.11.2020 00:25

Другие вопросы по теме