Decimal, what are those trailing zeros ?
Yesterday, I stumbled on something I didn’t expect at all…
An exception appeared while testing my code that I had been carefully writing following Design By Example..
Looking in my debugger my decimal two variables had value 4M.
But calling ToString on it led to different results : “4” and “4.00”…
What the heck ?! How come ?
I should have known this
Yes, the MSDN state it explicitly :
The scaling factor also preserves any trailing zeroes in a Decimal number. Trailing zeroes do not affect the value of a Decimal number in arithmetic or comparison operations. However, trailing zeroes can be revealed by the ToString method if an appropriate format string is applied.
And I did not know that, did you ?
Try it yourself
you can try it yourself :
Console.WriteLine(1m); // 1 Console.WriteLine(1.0m); // 1.0 Console.WriteLine(1.00m); // 1.00 Console.WriteLine(1m == 1.0m); // true Console.WriteLine(1m.ToString() == 1.0m.ToString()); // false
The decimal.Parse function also preserve trailing zeros :
Console.WriteLine(decimal.Parse("1.0", CultureInfo.InvariantCulture)); // 1.0 Console.WriteLine(decimal.Parse("1.000", CultureInfo.InvariantCulture)); // 1.000
The explanation
The decimal type internally represents values using an 96 bit integer and a negative power of 10 (between 0 and 28).
Those values are simply internally stored like this :
1.0 –> 10 * 10^-1
1.000 –> 1000 * 10^-3
You can check it using the decimal.GetBits method.
The trailing zeros are even maintained in arithmetical operations :
Console.WriteLine(2.0m * 3.00m); // 6.000
But are handled correctly by the equality and comparison methods :
Console.WriteLine(1m == 1.0m); // true Console.WriteLine(1m.GetHashCode() == 1.0m.GetHashCode()); // true
Do you know other secrets like this ?
Of course, my unit tests did not test case I didn’t expect to happen !
But, Hey ! If you knew it, you should have told me before !
What secret feature/behavior in the .Net framework or in the C# language do you know ?