Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiplication and division with decimals

Tags:

c#

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.

like image 742
Oliver Apel Avatar asked Mar 27 '14 07:03

Oliver Apel


2 Answers

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

like image 104
Jerric Lyns John Avatar answered Sep 28 '22 11:09

Jerric Lyns John


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.

like image 20
Soner Gönül Avatar answered Sep 28 '22 11:09

Soner Gönül