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

Я хочу использовать дорожку для изменения непрозрачности формы.

Это мой код:

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

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

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

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

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

 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; 
  • Проблемы сравнения с плавающей запятой MySQL
  • C: Приведение минимального 32-битного целого числа (-2147483648) к float дает положительное число (2147483648.0)
  • C #: преобразовать массив байтов в float
  • Почему код целочисленного кода дает неверный ответ?
  • Преобразовать число с плавающей запятой в определенную точность, а затем скопировать в строку
  • Арифметика с плавающей точкой не дает точных результатов
  • Почему я вижу двойную переменную, инициализированную некоторым значением, например 21.4, как 21.399999618530273?
  • Java: зачем вам нужно указывать 'f' в streamовом литерале?
  • Составляют ли какие-либо JIT-компиляторы JVM код, который использует векторизованные инструкции с плавающей запятой?
  • Как мне сделать сравнение с плавающей запятой?
  • Двойной расчет, создающий нечетный результат
  • Interesting Posts

    Каков оптимальный способ хранения NSDate в NSUserDefaults?

    Внешний жесткий диск всегда используется при попытке безопасного удаления

    Опции для игр удаленно в локальной сети?

    Найти местоположение внешней SD-карты

    Как добавить ограничения программно с помощью Swift

    Как вызвать широковещательный приемник при включении / выключении gps?

    Не удалось загрузить модуль memtrack Logcat Error

    Почему bit endianness является проблемой в битполях?

    Заполните непересекающиеся пустые ячейки со значением из ячейки над первым пробелом

    Ошибки компоновщика при компиляции против glib …?

    Угловое 2 – Что эквивалентно корневой области?

    когда статическая переменная загружается в java, время выполнения или время компиляции?

    Двойная загрузка Windows и Ubuntu – * но * с Ubuntu, уже установленным на отдельный жесткий диск

    Как я могу сгладить папку в Windows 7, если все имена файлов различны?

    Android – в чем смысл StableID?

    Давайте будем гением компьютера.