Search code examples
c#castingtype-conversionroundingmscorlib

Math.Round() while casting and calculating returning wrong result


I was just curious if anyone could explain to me why these different data types round differently in my code? (note: this is not how the variables are actually declared, it is how they are stored. I just displayed them like this for clarity)

double amount = 15 ;
double taxPercentage = 0.015;
decimal itemTax;

First, the un-rounded result:

itemTax = (decimal)(amount * taxPercentage);
  // itemTax returns -0.225

If I round first, then cast to decimal:

itemTax = (decimal)(Math.Round(amount * taxPercentage, 2, MidpointRounding.AwayFromZero));
  // itemTax returns -0.22 

If I cast to decimal first, then round:

itemTax = (decimal)(amount * taxPercentage);
itemTax = Math.Round(itemTax,2,MidpointRounding.AwayFromZero);
 //  itemTax returns -0.23

Does this have something to do with the way double types round vs. decimal types?


Solution

  • Indeed. Double (like float) is base-2 number and is actually an approximation of a decimal value. Unlike decimal values, it can't represent infinite precision numbers so your -0.025 values might really be -0.024999999999