web-dev-qa-db-ja.com

10進および数学演算

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)キャストが冗長になります。そして、それを削除すると、解決策に戻りますが、機能しません。助けて...?

18
Noceo

これを解決する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

編集:

mthingyはliteralと呼ばれます。すべてのタイプサフィックスまたはリテラルの詳細については、 ドキュメントはこちら を参照してください。

23
Mong Zhu

いくつかの種類の数字には、いくつかの接尾辞があります。次に例を示します。

 // 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と見なされることがあります。

4
SᴇM

数値の1つにm接尾辞を追加して、10進数にすることができます。

return BaseValue * (365 / 360m);
4
sofsntp

mサフィックスを使用します。

return 365m/360 * BaseValue;
4
Zumoka

あなたの例では、角かっこはそのままにしておくことができます。

return BaseValue*365/360;
2
Damien Flury

必要なのはダブルキャストの1つだけです。そう

return BaseValue * (decimal)(365/(double)360);

正常に動作します。

1つがdoubleになると、コンパイラはそれを非整数除算として扱うことを認識します。

あるいは

return (BaseValue*365)/360;

働くでしょう。

あるいは

return BaseValue*365/360;

乗算は除算よりも優先されるためです。

2

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の世界にとどまります。

2

ダブルをダブルで割ったものは(もちろん)ダブルです。したがって、結果をキャストすることは冗長です。

数値を小数として指定するだけの場合は短くなります。

 return BaseValue * (365m /360);
0
Amy

(ダブル)キャストのいずれかが冗長ですが、両方は冗長ではありません。操作のいずれかの引数がdoubleの場合、他の引数は自動的にdoubleにキャストされます。引数の1つを実数定数、たとえば365.0として記述できますか?

0
Gem Taylor