5

I´m new to C# and have now a Problem with mathematical stuff. Why can´t I mulitplicate or divide "simple" like this:

 decimal mLon1 = 0;
 decimal mLat1 = 0;
 decimal mFactor = 111021;
 decimal mRadius = 100;
 decimal mLat = 12.123;

 mLon1 = mLon - mRadius / Math.Abs(Math.Cos(((Math.PI / 180) * mLat)) * mFaktor);
 mLat1 = mLat - (mRadius / mFaktor);

Compiler Shows an error:

The Operator '*' can not be applied to operands of type 'double' and 'decimal'.

Same with Operator '/' ...

How can I get my code workin? Thx for any hint.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Oliver Apel
  • 1,808
  • 3
  • 19
  • 31
  • Didn't you also get a compile error in the line `decimal mLat = 12.123`? I believe you need to suffix it like this: `decimal mLat = 12.123M` – rexcfnghk Mar 27 '14 at 07:13
  • Break it down into small steps to identify which part is throwing the error. Without looking it up you may need some casts. – Peter Smith Mar 27 '14 at 07:13
  • decimal is for financial and monetary calculations, these variables should probably be double. – PMBjornerud Aug 16 '17 at 12:59

5 Answers5

4

C# is a type-safe language, what i meant by type safe is that the code allows the developer to be certain that a value or object will be of a certain type so that he/she can use it in a specific way without fear of unexpected or undefined behavior. C# only some implicit conversion of types like int to double

Change your code as shown below

decimal mLon1 = 0M;
decimal mLat1 = 0M;
decimal mFactor = 111021M;//mFactor is never used
decimal mRadius = 100M;
decimal mLat = 12.123M;

mLon1 = mLon - mRadius / Math.Abs(Convert.ToDecimal(Math.Cos((Math.PI / 180) * Convert.ToDouble(mLat))) * mFaktor);//mFaktor and mLon is not defined
mLat1 = mLat - (mRadius / mFaktor);

Here Convert.ToDouble(mLat) converts mLat to double since C# doesn't allow implicit conversion of decimal to double, why am I doing this? Well Math.Cos apparently accepts only double, so is the case of Math.Abs

Another workaround is that you could convert every declared variables as double and reduce the pain of explicit type conversions in between

double mLon1 = 0D;
double mLat1 = 0D;
double mFactor = 111021D;//mFactor is never used
double mRadius = 100D;
double mLat = 12.123D;

mLon1 = mLon - mRadius / Math.Abs(Math.Cos(((Math.PI / 180D) * mLat)) * mFaktor);//mFaktor and mLon is not defined
mLat1 = mLat - (mRadius / mFaktor);

Please see the below mentioned reference and what type is that you want to use in the present scenario that you are facing.

Floating point reference

Reference: MSDN

Jerric Lyns John
  • 936
  • 10
  • 25
2

You shouldn't use the decimal type for this usage. Use the double type and everything will be fine.

In your case, the math function returns a double precision floating point (64 bits) number and the decimal type is a 128 bits floating point non-native data type.

You can't directly multiply two numbers that don't have the same memory size.

2

First of all, your code doesn't even compile.

If you want to use 12.123 as a decimal, you need to use m or M suffix. If you don't use any suffix with your floating type, C# thinks it is a double.

From decimal (C# Reference)

If you want a numeric real literal to be treated as decimal, use the suffix m or M. Without the suffix m, the number is treated as a double and generates a compiler error.

And there are no implicit conversions between floating-point types (float and double) and the decimal type.

Since Math.PI field represents double, your Math.PI / 180 will be double. Since mLat is decimal (you said it is a spelling mistake) you try to get double * decimal which is clearly you get these error. You try to same operation with / operator also.

From C# Spec $7.7.1 Multiplication operator

float operator *(float x, float y);
double operator *(double x, double y);
decimal operator *(decimal x, decimal y);

And from C# Spec $7.7.2 Division operator

float operator /(float x, float y);
double operator /(double x, double y);
decimal operator /(decimal x, decimal y);

As you can see from these documentations, there is no defined double * decimal or double / decimal operations.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • OK, I understand the conversion matter now. But my main variables should be still `decimal`s because I´m working in this case with geo-Points within a database. I´ve read some Posts about the Problems with the behaviour based on base 10 representations (http://stackoverflow.com/questions/1165761/decimal-vs-double-which-one-should-i-use-and-when). Which type should I use in my case? I don´t need an accuracy of more than 10 Meters in my calculations... – Oliver Apel Mar 27 '14 at 07:55
0

try below code and you have spelling mistake near "mFaktor" which should be "mFactor"

decimal mLon1 = 0;
decimal mLat1 = 0;
decimal mFactor = 111021;
decimal mRadius = 100;
decimal mLat = (decimal)12.123;
decimal mLon = 0;
mLon1 = mLon - mRadius / (decimal)Math.Abs(Math.Cos(((Math.PI / 180) * (double)mLat)) * (double)mFactor);
mLat1 = mLat - (mRadius / mFactor);
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
Neel
  • 11,625
  • 3
  • 43
  • 61
  • 1
    Sorry, the spelling mistake is only in my Hand typed samlpe here. Your solution with the cast as double an decimal works. thx! – Oliver Apel Mar 27 '14 at 07:33
0

You could also use variables of type double instead of decimal.

Codor
  • 17,447
  • 9
  • 29
  • 56