Using C#, any idea why the following method returns 57.999999999999993 (instead of 58)?
double Test_Null_Coalescing_Operator()
{
double? x = 0.58;
return ((x ?? 0) * 100);
}
//returns 57.999999999999993 (instead of 58)
Using C#, any idea why the following method returns 57.999999999999993 (instead of 58)?
double Test_Null_Coalescing_Operator()
{
double? x = 0.58;
return ((x ?? 0) * 100);
}
//returns 57.999999999999993 (instead of 58)
On
Assuming double is IEEE 754 64-bit binary floating point, 0.58 is not exactly representable. The closest is 0.57999999999999996003197111349436454474925994873046875. After multiplying by 100, the rounding error on rounding up to 58 would be 3.99680288865056354552507400512695312500E-15, which is slightly bigger than the rounding error on rounding down to 57.99999999999999289457264239899814128875732421875, 3.10862446895043831318616867065429687500E-15
If you are representing physical quantities such as length, the measurement error will completely dwarf the rounding error, less than one part in 1015.
There are some special cases, such as some financial calculations, for which exact representation of short terminating decimal fractions is important. For those, you should generally use a decimal type, not double.
On
@Felipe Deveza already mentioned about the reason. If you want to receive exactly 0.58, you can use Math.Round()
On
The answers and the linked duplicate explain the reason, I just want to highlight a rule of thumb. Whenever the decimally written representation of the number is relevant use the decimal type instead. The float and double types are fast as they are directly supported by the CPU but use them only if their decimal representation is not important (eg. rendering, multimedia processing, etc.).
In many languages the decimal (or a similar decimal floating-point type for the same purpose) is called money suggesting that this is what you should use for financial calculations. And actually that's where the m postfix of the decimal comes from in C# as well (var x = 0.58m).
Rounding error. 0.58 not exists as a double.