Why c# decimals can't be initialized without the M suffix?

29,456

Solution 1

The type of a literal without the m suffix is double - it's as simple as that. You can't initialize a float that way either:

float x = 10.0; // Fail

The type of the literal should be made clear from the literal itself, and the type of variable it's assigned to should be assignable to from the type of that literal. So your second example works because there's an implicit conversion from int (the type of the literal) to decimal. There's no implicit conversion from double to decimal (as it can lose information).

Personally I'd have preferred it if there'd been no default or if the default had been decimal, but that's a different matter...

Solution 2

The first example is a double literal. The second example is an integer literal.

I guess it's not possible to convert double to decimal without possible loss of precision, but it is ok with an integer. So they allow implicit conversion with an integer.

Solution 3

Your answer i a bit lower in the same link you provided, also Here. In Conversions:

"The integral types are implicitly converted to decimal and the result evaluates to decimal. Therefore you can initialize a decimal variable using an integer literal, without the suffix".

So, the reason is because of the implicit conversion between int and decimal. And since 0.50 is treated as double, and there is not implicit conversion between double and decimal, you get your error.

For more details:

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

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

Solution 4

Every literal is treated as a type. If you do not chose the 'M' suffix it is treated as a double. That you cannot implicitly convert a double to a decimal is quite understandable as it loses precision.

Solution 5

Its a design choice that the creators of C# made.

Likely it stems that double can lose precision and they didn't want you to store that loss. int don't have that problem.

Share:
29,456
onof
Author by

onof

I'm Onofrio Panzarino. My preferred motto about software development is: "There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C. A. R. Hoare

Updated on July 02, 2020

Comments

  • onof
    onof almost 4 years
    public class MyClass
    {
        public const Decimal CONSTANT = 0.50; // ERROR CS0664   
    }
    

    produces this error:

    error CS0664: Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a literal of this type

    as documented. But this works:

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

    And I wonder why they forbid the first one. It seems weird to me.

  • Jessy
    Jessy about 12 years
    +1 for preferring no default. Doubles and decimals are largely useless to game developers, so declaring a default precision for literals, a la GLSL in OpenGL ES 2.0, could eliminate all the annoying F's everywhere.
  • supercat
    supercat almost 12 years
    @Jessy: If .net hadn't followed Java's lead in requiring silly typecasts from double-to-float but not vice versa (despite the fact that conversions from more-specific to less-specific types are supposed to be widening) would there be any problems with having numeric literals default to double? It shouldn't take much for a compiler to recognize when a literal is used for no purpose other than to assign a float, and convert it at compile time.
  • B. Clay Shannon-B. Crow Raven
    B. Clay Shannon-B. Crow Raven almost 10 years
    If this cat reaches 1 million points, will he receive a crown and a trident, be knighted, receive a lifetime supply of biscuits, or...???
  • Jeppe Stig Nielsen
    Jeppe Stig Nielsen almost 8 years
    While it is true that the conversion from double to decimal can lose information, in many cases it loses only precision because the value is rounded to 15 significant figures. Although in some cases, like 3.14159e-26, more precision is lost. However, the conversion can also easily overflow (if the operand is NaN or numerically exceeds approx. 8e28) which is another good reason for not making the conversion implicit (analogous to why narrowing integer conversions are not implicit).