正確な数値計算に欠かせない、decimal 型に関して、知っておいた方がよいことがあります。

ECMA CLI 標準に準拠するための内部的な変更があったようです。

[C#]
decimal value = 12.246000m;
Console.WriteLine(value.ToString());

V1.0 では 12.246
V1.1 では 12.246000

になります。

V2.0 以降でも V1.1 と同じですね(Visual Studio 2008で検証していませんが、た、たぶんそう)

変更された内容は、
「Decimal.ToString は、末尾のゼロを保持し、既定の ToString でそのゼロを表示するように変更」
というものです。

この、保持というのが曲者で、掛け算、文字列に変換したあとでの比較演算がおもしろいことになります。
その対策として、G29 書式 があります。
29 は、Decimal が保持できる最大の有効桁数であるため、丸めることなく、末尾のゼロを切り捨てる効果があります。

ということで、以下のコードの結果を予測してみてください。

decimal d1 = 1;

decimal d2 = 1.0m;

decimal d3 = d2 * d2;

decimal d4 = d3 * d3;

decimal d5 = d4 * d4;

decimal d6 = d5 * d5;

 

Console.WriteLine("d1 = " + d1.ToString());

Console.WriteLine("d2 = " + d2.ToString());

Console.WriteLine("d3 = " + d3.ToString());

Console.WriteLine("d4 = " + d4.ToString());

Console.WriteLine("d5 = " + d5.ToString());

Console.WriteLine("d6 = " + d6.ToString());

 

Console.WriteLine("d6 = " + d6.ToString("G29"));

 

//比較演算

if (d1 == d6)

{

    Console.WriteLine("decimal比較:d1d6は同じです");

}

if (d1.ToString() == d6.ToString())

{

    Console.WriteLine("decimal.Tostring()比較:d1d6は同じです");

}

if (d1.ToString("G29") == d6.ToString("G29"))

{

    Console.WriteLine("decimal.Tostring(\"G29\")比較:d1d6は同じです");

}

結果は以下です(反転させて見てね)

d1 = 1
d2 = 1.0
d3 = 1.00
d4 = 1.0000
d5 = 1.00000000
d6 = 1.0000000000000000
d6 = 1
decimal比較:d1とd6は同じです
decimal.Tostring("G29")比較:d1とd6は同じです

いかがでしたか?
調べてて、影響範囲はすくないかなーとかおもいつつ、知っておいた方がよい情報だなーと思いました。

d1.ToString() == d6.ToString()

に関しては、.NET Framework 1.0 とそれ以外のバージョンで実行結果が異なってしまいますが、
ま、、、、、影響範囲はそんなにないかな・・・・

ネタ元
Decimal.ToString は、なぜ V1.0 と V1.1 で異なるのですか。またどのように対処すればよいですか。
http://www.microsoft.com/japan/msdn/netframework/programming/bcl/faq/NumericTypesFAQ.aspx#Question4
 書いてみればわかりますが、ここのサンプルコードは微妙ですが間違ってます
 × Decimal             →  ○ decimal       C#の型は先頭小文字
 × ToString(G29) →  ○ ToString(“G29“)     書式指定子は、文字列で書く

# 修正履歴   やってもーた・・・ orz...
修正前
 × ToString(G29) →  ○ ToString(G29)     書式指定子は、文字列で書く
修正後
 × ToString(G29) →  ○ ToString(G29)     書式指定子は、文字列で書く