Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to compare decimals casted from doubles

It is commonly known that it is not safe to compare double values with == operator. In this example it returns false:

double d1 = 0.11;
double d2 = 0.44 - 0.33;
Console.WriteLine(d1 == d2);

But, if we cast values to decimal, it returns true:

double d1 = 0.11;
double d2 = 0.44 - 0.33;
Console.WriteLine((decimal)d1 == (decimal)d2);

Is it always safe to compare decimals casted from double, or there are some cases where can give unexpected result?

Update: Hossein's example is good, it shows that it can be wrongly true. But I'm more interested to see if there are opposite examples, when we expect decimal values to be equal and they are not. Even wider, what exactly happens when we cast from double to decimal.

like image 587
Alex Butenko Avatar asked Jan 30 '26 14:01

Alex Butenko


2 Answers

It is commonly known that it is not safe to compare double values in .net. In this example it returns false

You are mistaken about what is not safe.

It is not safe to assume that an arbitrary decimal representation, even if it is short (written in decimal), is represented exactly in binary floating-point. It is not safe to assume that - between binary floating-point values produces anything other than the nearest representable floating-point value to the mathematical result (and in particular, it is not safe to assume that it always produces the mathematical result).

d1 == d2 is perfectly safe, and so is (decimal)d1 == (decimal)d2. The first one will not always return what you appear to want, but neither will the second, because it has no reason to according to the principles laid out above. Once d1 and d2 have been computed, the approximations have already been done:

  • representation approximation, because you appear to think that 0.11 should be the mathematical value 11/100, and it's not, it's the nearest representable value;
  • operation approximation, because the mathematical result of 0.44 minus 0.33 may not be representable exactly, in which case the nearest representable value will be used.

The fact that these approximations compound and, when adding the third approximation of converting to decimalin C#, result in the value you expected is pure coincidence. If anything should be commonly known, it should be that it is too late to fix an approximation after it has occurred and that adding another approximation will not really help. See the first example in this article, Excel, another programmable product from Microsoft.

like image 52
Pascal Cuoq Avatar answered Feb 02 '26 04:02

Pascal Cuoq


In this case you may get the desired result but generally your answer is NO. When you store a value in a double then casting it to a decimal do not enhance its precision (link).

Consider the below example. The equality returns true but we expect false.

double myDouble1 = 0.11;
double myDouble2 = 0.10999999999999999;
Console.WriteLine((decimal)myDouble1 == (decimal)myDouble2); //true, but we expect false

But if you store those values as decimal, then the you will get the proper result.

decimal myDecimal1 = 0.11M;
decimal myDecimal2 = 0.10999999999999999M;
Console.WriteLine(myDecimal1 == myDecimal2); //false
like image 40
Hossein Narimani Rad Avatar answered Feb 02 '26 02:02

Hossein Narimani Rad



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!