How to Convert a Decimal to a Double in C#

Converting Decimal to Double in C#?

You answered your own question—Just cast it to a double:

decimal x  = 3.141592654M ;
double pi = (double) x ;

How to convert Decimal to Double in C#?

An explicit cast to double like this isn't necessary:

double trans = (double) trackBar1.Value / 5000.0;

Identifying the constant as 5000.0 (or as 5000d) is sufficient:

double trans = trackBar1.Value / 5000.0;
double trans = trackBar1.Value / 5000d;

Convert decimal? to double?

Built in casts for the win! Just tested this in VS2012 and VS2010:

 decimal? numberDecimal = new Decimal(5); 
decimal? nullDecimal = null;
double? numberDouble = (double?)numberDecimal; // = 5.0
double? nullDouble = (double?)nullDecimal; // = null

Just using an explicit cast will cast null to null, and the internal decimal value to double. Success!

Conversion of a decimal to double number in C# results in a difference

Interesting - although I generally don't trust normal ways of writing out floating point values when you're interested in the exact results.

Here's a slightly simpler demonstration, using DoubleConverter.cs which I've used a few times before.

using System;

class Test
{
static void Main()
{
decimal dcm1 = 8224055000.0000000000m;
decimal dcm2 = 8224055000m;
double dbl1 = (double) dcm1;
double dbl2 = (double) dcm2;

Console.WriteLine(DoubleConverter.ToExactString(dbl1));
Console.WriteLine(DoubleConverter.ToExactString(dbl2));
}
}

Results:

8224055000.00000095367431640625
8224055000

Now the question is why the original value (8224055000.0000000000) which is an integer - and exactly representable as a double - ends up with extra data in. I strongly suspect it's due to quirks in the algorithm used to convert from decimal to double, but it's unfortunate.

It also violates section 6.2.1 of the C# spec:

For a conversion from decimal to float or double, the decimal value is rounded to the
nearest double or float value. While this conversion may lose precision, it never causes
an exception to be thrown.

The "nearest double value" is clearly just 8224055000... so this is a bug IMO. It's not one I'd expect to get fixed any time soon though. (It gives the same results in .NET 4.0b1 by the way.)

To avoid the bug, you probably want to normalize the decimal value first, effectively "removing" the extra 0s after the decimal point. This is somewhat tricky as it involves 96-bit integer arithmetic - the .NET 4.0 BigInteger class may well make it easier, but that may not be an option for you.

How to convert from decimal to double in Linq to Entity

The difference between a float (double) and a decimal, is that a float is decimal precise. If you give the float a value of 10.123, then internally it could have a value 10.1229999999999, which is very near to 10.123, but not exactly.

A decimal with a precision of x decimals will always be accurate until the x-th decimal.

The designer of your database thought that type A didn't need decimal accuracy (or he was just careless). It is not meaningful to give the result of a calculation more precision than the input parameters.

If you really need to convert your result into a decimal, calculate your formula as float / double, and cast to decimal after AsEnumerable:

(I'm not very familiar with your syntax, so I'll use the extension method syntax)

var list = model.Table.Where(row => row.A * row.B < 1000)
.Select(row => new
{
A = row.A,
B = row.B,
})
.AsEnumerable()
.Select(row => new
{
A = row.A,
B = row.B,
C = (decimal)row.A * (decimal)row.B,
});

Meaning:

  • From my Table, take only rows that have values such that row.A * row.B
    < 1000.
  • From each selected row, select the values from columns A and B.
  • Transfer those two values to local memory (= AsEnumerable),
  • for every transferred row create a new object with three properties:

    • A and B have the transferred values.
    • C gets the the product of the decimal values of transferred A and B

Convert decimal[][] to double[][] in C#

Unfortunately with a jagged array you'll have to convert each array separately, but it can still be done in a one-liner:

doubleArray = Array.ConvertAll(decimalArray, da => Array.ConvertAll(da, d => (double)d));

or using Linq:

doubleArray = decimalArray.Select(da => da.Select(d => (double)d).ToArray()).ToArray(); 

You'll have to try it to see which is faster; Array.ConvertAll may have some optimizations by combining the delegate and the Array creation.

BENCHMARKS

to address the debate of performance, I benchmarked the three proposed solutions:

  1. Array.Convert
  2. Linq
  3. Loops

Here are the code and the results

int I = 10000;
int J = 1000;

Random rand = new Random();

decimal[][] decimalArray = new decimal[I][];

decimalArray = Enumerable.Range(1,I).Select(i =>
Enumerable.Range(1, J).Select (j => (decimal)rand.NextDouble()).ToArray()
).ToArray();

Stopwatch s = new Stopwatch();

// Array.ConvertAll
s.Start();
var doubleArray = Array.ConvertAll(decimalArray, da => Array.ConvertAll(da, d => (double)d));
s.Stop();
s.Dump();

// Linq
s.Restart();
doubleArray = decimalArray.Select(da => da.Select(d => (double)d).ToArray()).ToArray();
s.Stop();
s.Dump();

// Loops
s.Restart();
doubleArray = new double[I][];
for(int i = 0; i < I; i++)
{
decimal[] dda = decimalArray[i];
doubleArray[i] = new double[dda.Length];
double[] da = doubleArray[i];
for(int j = 0; j < dda.Length; j++)
{
da[j] = (double)dda[j];
}
}
s.Stop();
s.Dump();

Method ElapsedMilliseconds
------------- ----------------------
Array.Convert 310
Linq 478
Loops 287 (7.5% faster that Array.Convert)

You can decide whether a 7.5% speed improvement is worth 7X the amount of code.

How do I display a decimal value to 2 decimal places?

decimalVar.ToString("#.##"); // returns ".5" when decimalVar == 0.5m

or

decimalVar.ToString("0.##"); // returns "0.5"  when decimalVar == 0.5m

or

decimalVar.ToString("0.00"); // returns "0.50"  when decimalVar == 0.5m

Test whether a decimal value can be converted to double

What's a good method to test whether a decimal value can be converted to double without throwing an exception?

static bool CanBeConvertedToDouble(decimal d)
{
return true;
}

:)

All decimals can be converted to double.

Note that doing so will possibly lose immense amounts of precision. A decimal has about 29 decimal places of precision; a double has only 15 or so. But converting a decimal to double never loses magnitude.



Related Topics



Leave a reply



Submit