Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decimal and mathematical operations

I have a simple conversion of a decimal in C#. It looks like this:

private decimal BaseValue
{
    get; set;
}

public decimal ConvertedValue 
{
    get
    {
        return BaseValue * (365 / 360);
    }
}

However, this does not work. I assume because C# is processeing the numbers in the fraction as integers. So I can do like this instead (which works):

public decimal ConvertedValue 
{
    get
    {
        return BaseValue * (decimal)((double)365 / (double)360);
    }
}

Now this seems a bit like overkill, but I can live with that. My primary question is this:

Why does Visual Studio warn me that 'Cast is redundant', for the (double) cast? And if I remove the (double) cast, then the (decimal) cast becomes redundant. And if I remove that, then I am back to the solution, which does not work. Help...?

like image 774
Jakob Busk Sørensen Avatar asked Sep 20 '17 13:09

Jakob Busk Sørensen


2 Answers

one way to solve this is by specifying that the numbers in the calculation are decimal with a m at the end

return BaseValue * (365m / 360m);

Why does Visual Studio warn me that 'Cast is redundant', for the (double) cast

because when you have a double on one side of the equation then the result will be a double.

(double)365 / (double)360

have a look at the documentation of the * operator overloads. You will see that the operands are always of the same type like:

decimal operator *(decimal x, decimal y);


... then the (decimal) cast becomes redundant.

again, because when you have a decimal on one side of the equation then the result will be a decimal:

BaseValue * (decimal)(365 / 360)

The problem here is the scope! you cast the entire result of the division to decimal . Actually you could solve your problem simply by removing the parentheses:

return BaseValue * 365 / 360;

this way you equation will be correct, because the result of the * multiplication will be a decimal (since one of the operands is a decimal, so the other will be casted implicitly) and again the result of the division will also be a decimal for the same reason.

NOTE: Removing the parentheses is in general not the same as leaving them in. In some cases, floating-point operations differ in the result when the order of such operations changes, even though the two expressions are mathematically identical. Comment by Banex

EDIT:

The m thingy is called a literal. More information for all type-suffixes or literals can be found on the documentation here

like image 55
Mong Zhu Avatar answered Oct 14 '22 18:10

Mong Zhu


The decimal cast is redundant, because the compiler knows you want to return a decimal.

One of the two double casts is redundant, because when you cast one of the ints into a double, it's clear that you use the double division operator instead of integer division.

But it should be enough to just use the decimal literal suffix m:

return BaseValue * (365m / 360);

Again, one m is enough to infer the correct operator.


But hey, BaseValue already is decimal and the parenthesis don't make sense (if you don't want integer divivsion)... this should work, too:

return BaseValue * 365 / 360;
like image 43
René Vogt Avatar answered Oct 14 '22 18:10

René Vogt