Changes to Decimal.ToString between V1.0 and V1.1

[Anthony Moore]

There was a change to Decimal class in V1.1 to preserve trailing zeros in the default foramtting. I thought this was well known, but we just recently got a customer support issue on it. Here is an entry that we will shortly add to the numerics FAQ.

Why did Decimal.ToString change between V1.0 and V1.1 and how do I work around it?

In general there were very few breaking changes between V1.0 and V1.1. One of the more noticeable ones was that Decimal.ToString changed to preserve trailing zeros and the default ToString displays them.


Decimal value = 12.246000m;



In V1.0 this printed “12.246”. In V1.1 this prints “12.246000”. This was an intentional change in order to adhere to the ECMA CLI standard.


Note that this change only affects formatting. The values “12.246” and “12.246000” are still considered to be the same value if you compare them or do arithmetic on them. The trailing zeros, or scale, of the decimal is peripheral information that is preserved across most operations, but is not significant to the equality of the value. As such, this should only break code that depends on the specific string format.


To work around this and go back to the V1.0 behavior, use the “G29” format:


Decimal value = 12.246000m;



This will print “12.246” in either version 1.0 or version 1.1. The “G” format with a number means to format that many significant digits. Because 29 is the most significant digits that a Decimal can have, this will effectively truncate the trailing zeros without rounding.




Comments (7)

  1. Anonymous says:

    G29 – Doh! You sunk my battleship. Sorry, couldn’t resist. PS – Thanks for the tip. 🙂

  2. Anonymous says:

    G29 s a decimal.tostring

  3. Anonymous says:

    WIll the ToString() use the locale decimal separator, or will it use . all the time

    I’ve run into SOAP trouble around this — 1.234 gets turned into 1,234 in Europe, and then the deserializer in the US craps out because , is not the decimal separator.

    Not fun. I probably want to complain to the SOAP people instead of here, but thought I’d mention it just in case.

  4. Anonymous says:

    Hey there Christian,

    Like most of our base APIs, cutlure is respected by default, unless you specifically tell us not to. You can control formatting by ensuring that any API which is about to be formatted as a string, is formatted in a specific way. For DateTime, you could decide to either use a culture neutral output format (such as ‘s’) or always use the InvairantCulture when formatting the DateTime.

  5. Anonymous says:

    And I just realized I had DateTime’s on the brain: ignore the comment regarding ‘s’ for Decimal, but you can still use the ToString overload that accepts the IFromatProvider to ensure that the format is consistent, regardless of the culture:

    using System;

    using System.Threading;

    using System.Globalization;

    public class C


    public static void Main() {

    Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES");

    Decimal d = 12331.234558m;

    // this will change with the above culture


    // this will not change




  6. Anonymous says:

    <p>&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;; target=&quot;_blank&quot;&gt; Reflector&lt;/a&gt; és &lt;a href=&quot;