3

When I try to declare a variable like this:

decimal order = 5.0;

I get the error message "Literal of type double cannot be implicitly converted to type 'decimal'; use an 'M' suffix to create a liter of this type."

Can someone explain why the M is needed?

Mike G
  • 4,232
  • 9
  • 40
  • 66
ELang
  • 31
  • 1
  • 3
  • 2
    Because `5.0` is a double and not a decimal. And a conversion from `double` to `decimal` isn't automatic and can't be because their ranges are not the same. – Matt Burland Jul 22 '15 at 19:08
  • You should probably just use double to not have to worry about the M – FirebladeDan Jul 22 '15 at 19:09
  • 2
    @FirebladeDan Bad idea - double and float are horrible choices for variables that represent actual decimal amounts (money, percentages, etc.) they are good for naturally imprecise measurements (temperature, height, etc.) – D Stanley Jul 22 '15 at 19:12
  • You *can* use `decimal order = 5;` because of the implicit conversion from integer types to `decimal`. But that will become `5M` (after the invisible conversion) which is not quite the same as `5.0M`. – Jeppe Stig Nielsen Jul 22 '15 at 19:16
  • @DStanley - I think you exaggerated that quite a bit. Double will work just fine for his order 5.0 with ONE SIGNIFICANT DIGIT. I doubt he'll need the 20+ digits unless he's building a robot to do spinal surgery... – FirebladeDan Jul 22 '15 at 19:24
  • 3
    @FireBladeDan It's not about the precision, it's about accurate binary representation. `(0.15 + 0.15 == 0.10 + 0.20)` will return `false`. Good luck explaining that to your accounting manager. – D Stanley Jul 22 '15 at 19:31
  • @FirebladeDan Status: Currently Seeking Employment. (Learned something *thanks @DStanley) – FirebladeDan Jul 22 '15 at 19:49

2 Answers2

2

Any numeric literal with a decimal point but no suffix is of type double. From the C# 5 specification, section 2.4.4.3:

If no real-type-suffix is specified, the type of the real literal is double. Otherwise, the real type suffix determines the type of the real literal, as follows: [...]

There's no implicit conversion from double to decimal, so trying to assign a double value to a decimal variable fails.

You'd get the same thing if you wanted a float value:

float x = 5.0; // Nope, same problem

You could explicitly cast to float or decimal, but that would be a bad idea for float and a very bad idea for decimal.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
2

MSDN:decimal C# reference

If you want a numeric real literal to be treated as decimal, use the suffix m or M, for example:

decimal myMoney = 300.5m;

Without the suffix m, the number is treated as a double and generates a compiler error.

ZeroBased_IX
  • 2,667
  • 2
  • 25
  • 46