How Did System.Decimal Change from V1.0 to V1.1? [Anthony Moore]

There were very few noticeable changes between the V1.0 and the V1.1 release. One change that people sometimes notice is that Decimal looks different across the two versions. The changes are largely cosmetic, although in some rare cases applications have been affected.

 

Decimal was revised to comply with a late update to the CLI, an ECMA standard to which the .NET Framework is compliant. It changed to store the information about how many trailing zeros exist. It also preserves this information across arithmetic operations and the default Decimal.ToString changed to include this information.

 

Consider the following code:

 

[vb]

Dim mediumDecimal as Decimal = "5.100"

Dim smallDecimal as Decimal = "0.00000000600"

Console.WriteLine("mediumDecimal.ToString() = '{0}'", mediumDecimal.ToString())

Console.WriteLine("smallDecimal.ToString() = '{0}'", smallDecimal.ToString())

Console.WriteLine("(mediumDecimal/2).ToString() = '{0}'", (mediumDecimal/2).ToString())

Console.WriteLine("(smallDecimal/2).ToString() = '{0}'", (smallDecimal/2).ToString())

 

In V1.0, this outputs the following:

 

mediumDecimal.ToString() = '5.1'

smallDecimal.ToString() = '6E-09'

(mediumDecimal/2).ToString() = '2.55'

(smallDecimal/2).ToString() = '3E-09'

 

In V1.1, this outputs the following

 

mediumDecimal.ToString() = '5.100'

smallDecimal.ToString() = '0.00000000600'

(mediumDecimal/2).ToString() = '2.550'

(smallDecimal/2).ToString() = '0.00000000300'

 

What you can see here is that by default Decimal.ToString will include trailing zeros, and the amount of trailing zeros are preserved across arithmetic. You can also see that the default Decimal.ToString also has a change of behavior in that if the number is extremely small, it will output all the digits instead of switching to more concise scientific notation.

 

You may be wondering what to do if you take a dependency on this behavior, or if you have an application that targets multiple version of the .NET framework. The following code shows formats that will work in either version and will mimic the V1.0 or V1.1 default string format:

 

[vb]

Dim mediumDecimal as Decimal = "5.100"

Dim smallDecimal as Decimal = "0.00000000600"

Dim v10Default as String = "G29"

Console.WriteLine("mediumDecimal.ToString(""{0}"") = '{1}'", v10Default, mediumDecimal.ToString(v10Default))

Console.WriteLine("smallDecimal.ToString(""{0}"") = '{1}'", v10Default, smallDecimal.ToString(v10Default))

Dim v11Default as String = "0.#############################"

Console.WriteLine("mediumDecimal.ToString(""{0}"") = '{1}'", v11Default, mediumDecimal.ToString(v11Default))

Console.WriteLine("smallDecimal.ToString(""{0}"") = '{1}'", v11Default, smallDecimal.ToString(v11Default))

 

On both versions, this will output the following:

 

mediumDecimal.ToString("G29") = '5.1'

smallDecimal.ToString("G29") = '6E-09'

mediumDecimal.ToString("0.#############################") = '5.1'

smallDecimal.ToString("0.#############################") = '0.000000006'