web-dev-qa-db-ja.com

Mサフィックスなしでc#の小数を初期化できないのはなぜですか?

public class MyClass
{
    public const Decimal CONSTANT = 0.50; // ERROR CS0664   
}

このエラーが発生します:

エラーCS0664:タイプdoubleのリテラルは、タイプ 'decimal'に暗黙的に変換できません。このタイプのリテラルを作成するには、「M」サフィックスを使用します

ドキュメント として。しかし、これはうまくいきます:

public class MyClass
{
    public const Decimal CONSTANT = 50; // OK   
}

そして、なぜ彼らは最初のものを禁じているのでしょうか。それは私には奇妙なようです。

35
onof

リテラルのタイプなしmサフィックスはdoubleです-それはそれと同じくらい簡単です。 floatをそのように初期化することもできません。

float x = 10.0; // Fail

リテラルのタイプはリテラル自体から明確にする必要があり、割り当てられる変数のタイプはfromに割り当て可能である必要がありますそのリテラルのタイプ。したがって、int(リテラルのタイプ)からdecimalへの暗黙的な変換があるため、2番目の例は機能します。 doubleからdecimalへの暗黙的な変換はありません(情報が失われる可能性があるため)。

個人的にはno defaultがあった場合、またはdefaultがdecimalだった場合にそれを選択しましたが、それは別の問題です...

47
Jon Skeet

最初の例は二重リテラルです。 2番目の例は整数リテラルです。

精度を落とすことなくdoubleをdecimalに変換することは不可能だと思いますが、整数でも問題ありません。したがって、整数を使用した暗黙の変換が可能です。

11
James Johnston

すべてのリテラルはタイプとして扱われます。 'M'サフィックスを選択しない場合は、doubleとして扱われます。 暗黙的にdoubledecimalに変換できないことは、精度が失われるため、かなり理解できます。

5
Oskar Kjellin

あなたの答えは、あなたが提供した同じリンクで少し低く、また ここ です。コンバージョン:

「整数型は暗黙的に10進数に変換され、結果は10進数に評価されます。したがって、接尾辞なしで整数リテラルを使用して10進変数を初期化できます。」.

その理由は、intとdecimalの間の暗黙的な変換のためです。そして、0.50はdoubleとして扱われ、doubleとdecimalの間の暗黙的な変換がないため、エラーが発生します。

詳細については:

http://msdn.Microsoft.com/en-us/library/y5b434w4(v = vs.80).aspx

http://msdn.Microsoft.com/en-us/library/yht2cx7b.aspx

5
AJC

これは、C#の作成者が行った設計上の選択です。

doubleが精度を失う可能性があり、その損失を保存することを望まなかった可能性があります。 intそのような問題はありません。

4
Daniel A. White

From http://msdn.Microsoft.com/en-us/library/364x0z75.aspx :浮動小数点型と10進数型の間の暗黙的な変換はありません。したがって、これらの2つのタイプ間の変換にはキャストを使用する必要があります。

Doubleには非常に広い範囲があるため、これを行います±5.0×10−324 ±1.7×10まで308 一方、intは-2,147,483,648〜2,147,483,647です。小数の範囲は(-7.9 x 1028 7.9 x 10まで28)/(100から28)そのため、intは保持できますがdoubleは保持できません。

3
Paul