C#でdecimal
を簡単に変換しました。次のようになります。
private decimal BaseValue
{
get; set;
}
public decimal ConvertedValue
{
get
{
return BaseValue * (365 / 360);
}
}
ただし、これは機能しません。 C#が分数の数値を整数として処理しているためだと思います。だから私は代わりにこのようにすることができます(これはうまくいきます):
public decimal ConvertedValue
{
get
{
return BaseValue * (decimal)((double)365 / (double)360);
}
}
今、これは少しやり過ぎのように思えますが、私はそれで生きることができます。私の主な質問はこれです:
(double)
キャストに対して、Visual Studioが「キャストが冗長である」と警告するのはなぜですか?そして、(double)
キャストを削除すると、(decimal)
キャストが冗長になります。そして、それを削除すると、解決策に戻りますが、機能しません。助けて...?
これを解決する1つの方法は、計算の数値がdecimal
であり、最後にm
が付いていることを指定することです。
_return BaseValue * (365m / 360m);
_
Visual Studioが(ダブル)キャストに対して「キャストが冗長である」と警告するのはなぜですか
方程式の片側にdouble
がある場合、結果はdoubleになるためです。
_(double)365 / (double)360
_
*演算子のオーバーロードのドキュメント をご覧ください。オペランドは常に次のような同じタイプであることがわかります。
decimal operator *(decimal x, decimal y);
...その後、(10進数の)キャストは冗長になります。
繰り返しますが、方程式の片側にdecimal
がある場合、結果は小数になります。
_BaseValue * (decimal)(365 / 360)
_
ここでの問題はスコープです!除算の結果全体をdecimal
にキャストします。実際には、括弧を削除するだけで問題を解決できます。
_return BaseValue * 365 / 360;
_
_*
_乗算の結果はdecimal
になるため、このように方程式は正しくなります(オペランドの1つはdecimal
であるため、もう1つは暗黙的にキャストされます) )また、同じ理由で、除算の結果も小数になります。
注:括弧を削除することは、一般に、括弧を残すことと同じではありません。場合によっては、浮動小数点演算は、次の順序で結果が異なることがあります。 2つの式が数学的に同一であっても、このような演算は変化します。コメント Banex
編集:
m
thingyはliteralと呼ばれます。すべてのタイプサフィックスまたはリテラルの詳細については、 ドキュメントはこちら を参照してください。
いくつかの種類の数字には、いくつかの接尾辞があります。次に例を示します。
// Use long suffix.
long l1 = 10000L;
// Use double suffix.
double d1 = 123.764D;
// Use float suffix.
float f1 = 100.50F;
// Use unsigned suffix.
uint u1 = 1000U;
// Use decimal suffix.
decimal m2 = 4000.1234M;
// Use unsigned suffix and long suffix.
ulong u2 = 10002000300040005000UL;
接尾辞は数値タイプを指定します。これらは、1000などの整数リテラルが特定のタイプの数値(たとえば、long(1000L))と見なされるようにC#コンパイラに指示します。数値に数値の接尾辞を追加する方法を検討します。
あなたの場合:
public decimal ConvertedValue
{
get
{
return BaseValue * (365 / 360M);
}
}
また、大文字の接尾辞を使用すると、より明確になります。
小文字のサフィックス。 u、l、ul、f、d、mなどの小文字のサフィックスを指定することもできます。しかし、これらは数字と混同しやすいです。文字「l」は、数字の1と見なされることがあります。
数値の1つにm接尾辞を追加して、10進数にすることができます。
return BaseValue * (365 / 360m);
mサフィックスを使用します。
return 365m/360 * BaseValue;
あなたの例では、角かっこはそのままにしておくことができます。
return BaseValue*365/360;
必要なのはダブルキャストの1つだけです。そう
return BaseValue * (decimal)(365/(double)360);
正常に動作します。
1つがdoubleになると、コンパイラはそれを非整数除算として扱うことを認識します。
あるいは
return (BaseValue*365)/360;
働くでしょう。
あるいは
return BaseValue*365/360;
乗算は除算よりも優先されるためです。
m
サフィックスを使用すると、単純に10進リテラルを使用できます。
public decimal ConvertedValue
{
get
{
return BaseValue * (365m/360);
}
}
2番目のキャストが冗長である理由は、C#が((double)365 / (double)360)
式の最初の数値(365)がdouble
であると導出するためです。したがって、除算を計算するために、2番目の項目も暗黙的にdouble
に変換します。したがって、2番目の要素として(double)
を書き込むかどうかは関係ありません。
csharp> (double) 365/350
1.04285714285714
csharp> (double) 365/ (double) 350
1.04285714285714
それでも、doubleにキャストしてからdecimalに戻すことはまったく役に立ちません。式で1つの10進数リテラルを使用すると、他の数値も10進数になり、decimal
の世界にとどまります。
ダブルをダブルで割ったものは(もちろん)ダブルです。したがって、結果をキャストすることは冗長です。
数値を小数として指定するだけの場合は短くなります。
return BaseValue * (365m /360);
(ダブル)キャストのいずれかが冗長ですが、両方は冗長ではありません。操作のいずれかの引数がdoubleの場合、他の引数は自動的にdoubleにキャストされます。引数の1つを実数定数、たとえば365.0として記述できますか?