136

How does one cast a double to decimal which is used when doing currency development. Where does the M go?

decimal dtot = (decimal)(doubleTotal);
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122
flo
  • 1,471
  • 2
  • 12
  • 13

5 Answers5

125

You only use the M for a numeric literal, when you cast it's just:

decimal dtot = (decimal)doubleTotal;

Note that a floating point number is not suited to keep an exact value, so if you first add numbers together and then convert to Decimal you may get rounding errors. You may want to convert the numbers to Decimal before adding them together, or make sure that the numbers aren't floating point numbers in the first place.

orad
  • 15,272
  • 23
  • 77
  • 113
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • as a follow up question, why is the explicit conversion needed? I've tried it out and I get an error that a double cannot be explicitly cast to a decimal, but doesn't a decimal carry more precision? (i.e. much like casting from an int to a double can be implicit.) –  Aug 14 '14 at 18:35
  • 7
    @Cortana: The precision of a decimal is higher, but the range is smaller. A double value may be out of range for a decimal. See: http://stackoverflow.com/questions/7817866/why-cant-double-be-implicitly-cast-to-decimal – Guffa Aug 14 '14 at 18:59
58

You can cast a double to a decimal like this, without needing the M literal suffix:

double dbl = 1.2345D;
decimal dec = (decimal) dbl;

You should use the M when declaring a new literal decimal value:

decimal dec = 123.45M;

(Without the M, 123.45 is treated as a double and will not compile.)

Chris Fulstow
  • 41,170
  • 10
  • 86
  • 110
35

use default convertation class: Convert.ToDecimal(Double)

Brant Olsen
  • 5,628
  • 5
  • 36
  • 53
Timur Sadykov
  • 10,859
  • 7
  • 32
  • 45
  • 1
    No because it will throw an OverflowException double vol_y = (double)Decimal.MaxValue + 10E+28D; Console.WriteLine("Convert.ToDecimal(vol_y) = " + Convert.ToDecimal(vol_y)); – ToXinE Dec 01 '14 at 15:23
  • 9
    @ToXinE IMHO in most cases an OverflowException is better than a silently creating wrong data – this.myself Nov 27 '19 at 11:04
16
Convert.ToDecimal(the double you are trying to convert);
Tom
  • 1,187
  • 2
  • 12
  • 21
  • Really, you're suggesting a call to a Convert method instead of a cast operator?? – Peter Ritchie May 15 '11 at 13:15
  • 2
    I've learnt that the Convert class is much more flexible and safe than a cast in C#. – Tom May 17 '11 at 00:20
  • 4
    "Safe"? as in when it can't cast it throws an exception at run-time instead of a compiler error? I've been bitten by that so many times that I actively avoid Convert... – Peter Ritchie May 20 '11 at 16:32
  • That's true, I usually know what I'm converting so in that case I use the Convert class. A simple try catch could get rid of the error but I agree it is more work. – Tom May 24 '11 at 20:16
  • 9
    @PeterRitchie thread is a bit old but this should be said: Calling the Convert method directly would be the more appropriate approach. Maybe I'm just an optimization freak but one less instruction to resolve is a bonus (since using the explicit (Type) cast syntax is just an operator overload that calls Convert). – Mike Johnson Aug 22 '13 at 16:44
  • 2
    @PeterRitchie: From a language-design perspective, it would have been better to require a programmer to use one of two conversion methods rather than allowing a typecast from `double` to `decimal`, given that for a `double` value like (1000000.0/3.0) one would in some cases want to clip "excess" precision yielding 333333.333333333D, but in others cases one would want to retain it, yielding 333333.333333333313931D. Rather than simply saying "convert to decimal", code should specify how that conversion should be performed. – supercat May 16 '14 at 22:21
  • @supercat I don't see how "two conversion methods" would be from a language-design perspective. The would have to do with interface design using the language in question. Given that the OP only details that a given `double` needs to be assigned to a `decimal`, I don't see how anyone could infer how the conversion *should be performed* and thus which of these two non-existent methods could be chosen for an answer to the question. I agree, it would be great if the question included that detail; but it didn't – Peter Ritchie May 16 '14 at 23:28
  • 1
    @PeterRitchie: From a language design perspective, I would favor allowing casts only in cases where any value in the source type would have one clearly and unambiguously "best" value in the destination type. For conversion from `Decimal` to `Double`, that would apply, but for conversion from `Double` to `Decimal` it would not. – supercat May 16 '14 at 23:47
  • 2
    @supercat which really seems unrelated to my first comment because using `Convert.ToDecimal(double)` is the same as `(decimal)doubleTotal`, except if `doubleTotal` changed to a different type you'd probably avoid a compile-time error and introduce a harder-to-find run-time error because a *different* ToDecimal override might get called. Cast operator is much more explicit... – Peter Ritchie May 17 '14 at 00:03
2

Well this is an old question and I indeed made use of some of the answers shown here. Nevertheless, in my particular scenario it was possible that the double value that I wanted to convert to decimal was often bigger than decimal.MaxValue. So, instead of handling exceptions I wrote this extension method:

    public static decimal ToDecimal(this double @double) => 
        @double > (double) decimal.MaxValue ? decimal.MaxValue : (decimal) @double;

The above approach works if you do not want to bother handling overflow exceptions and if such a thing happen you want just to keep the max possible value(my case), but I am aware that for many other scenarios this would not be the expected behavior and may be the exception handling will be needed.

taquion
  • 2,667
  • 2
  • 18
  • 29
  • 3
    This would fail in the following case double _double = (double)decimal.MaxValue; I would suggest using >= in the comparison public static decimal ToDecimal(this double _double) => _double >= (double) decimal.MaxValue ? decimal.MaxValue : (decimal) _double; – Martin Eyles Oct 30 '19 at 18:01