10 進数を 2 進数に変換しますか?
-
08-06-2019 - |
質問
トラックバーを使用してフォームの不透明度を変更したいと考えています。
これは私のコードです:
decimal trans = trackBar1.Value / 5000;
this.Opacity = trans;
アプリケーションをビルドすると、次のエラーが表示されます。
暗黙的に型を変換することはできません
'decimal'
に'double'
.
使ってみた trans
そして double
しかし、その後コントロールが機能しません。このコードは、過去の VB.NET プロジェクトでは正常に動作しました。
解決
次のような double への明示的なキャストは必要ありません。
double trans = (double) trackBar1.Value / 5000.0;
定数を次のように識別する 5000.0
(または 5000d
) 十分なものです:
double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;
他のヒント
「Decimal vs Double?」という一般的な質問に対する、より一般的な回答: 10進数 精度を維持するための金銭計算の場合、 ダブル 小さな違いに影響されない科学的な計算に。Double は CPU にネイティブな型であるため (内部表現は 基数 2)、Double を使用して行われた計算は、Decimal よりもパフォーマンスが高くなります (次のように表されます)。 10進数 内部的に)。
VB.NET では暗黙的にキャストが行われるため、コードは正常に動作しましたが、C# には暗黙的キャストと明示的キャストの両方があります。
C# では、精度が失われるため、10 進数から double への変換は明示的です。たとえば、1.1 は double として正確に表現できませんが、10 進数として表現できます (「」を参照)浮動小数点数 - 思ったよりも不正確」という理由で)。
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;
}
あなたには 2 つの問題があります。初め、 Opacity
10 進数値ではなく倍精度数値が必要です。コンパイラーは、10 進数と倍精度浮動小数点数の間の変換は行われますが、それが機能するためには明示的な変換を指定する必要があることを示しています。2つ目は、 TrackBar.Value
は整数値であり、int を int で割ると、変数の種類に関係なく int になります。この場合、int から 10 進数または double への暗黙的なキャストが行われます。キャスト時に精度が失われることがないため、コンパイラーはエラーを出しませんが、おそらく、取得される値は常に 0 になります。 trackBar.Value
常に 5000 未満です。解決策は、double (Opacity のネイティブ型) を使用するようにコードを変更し、定数を明示的に double にすることで浮動小数点演算を行うことです (演算を促進する効果があります)。またはキャストすることです。 trackBar.Value
double にすると、同じこと、または両方が行われます。ああ、他の場所で使用しない限り、中間変数は必要ありません。いずれにしても、コンパイラーがそれを最適化して取り除くだろうと思います。
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
は double 値であり、コンパイラーは、それに 10 進数値を詰め込むことを好みません。
使用する必要があります 5000.0
の代わりに 5000
.
の 不透明度 プロパティは double 型です。
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 に変更したときにコントロールが機能しない理由は、次のことが原因でした。
double trans = trackbar1.Value / 5000;
を解釈したのは 5000
整数として、そしてなぜなら trackbar1.Value
も整数です trans
値は常にゼロでした。を追加して数値を明示的に浮動小数点値にすることで、 .0
コンパイラはこれを double として解釈し、適切な計算を実行できるようになりました。
最良の解決策は次のとおりです。
this.Opacity = decimal.ToDouble(trackBar1.Value/5000);
以来 Opacity
は double 値です。最初から double を使用するだけで、キャストは一切行いませんが、精度が失われないように、除算するときは必ず double を使用してください。
Opacity = trackBar1.Value / 5000.0;
this.Opacity = trackBar1.Value / 5000d;