Comparing float and double data types in objective

2019-01-10 15:24发布

问题:

When using double or float data type in an iPhone app, I am running into problems with ">=" and "<=" comparisons because when a variable is assigned a number entered with one decimal place, such as 4.2, the float or double used in the comparison actually may have a value such as 4.1999998092651367. Because of this difference, a comparison such as ">= 4.2" is false instead of true. How can I avoid this problem?

回答1:

when a variable is assigned a number entered with one decimal place, such as 4.2, the float or double used in the comparison actually may have a value such as 4.1999998092651367

Not may. will. To be specific:

float f = 4.2;  // f is exactly 4.19999980926513671875
double d = 4.2; // d is exactly 4.20000000000000017763568394002504646778106689453125

The problem comes when you write something like:

float f = 4.2;
if (f >= 4.2) {
    // this block of code is not executed.
}

f is exactly 4.19999980926513671875, but you're comparing it to the double-precision literal "4.2", which has the value 4.20000000000000017763568394002504646778106689453125, so the comparison fails. If instead you compare against the single precision literal "4.2f":

float f = 4.2;
if (f >= 4.2f) {
    // this block of code is exectued.
}

the comparison succeeds, because the values are exactly equal. Floating-point is complicated, but it is entirely deterministic; one of the simplest things you can do to make it more intuitive is to not mix precisions. If you're working with float, make sure all of your literals are suffixed with f to make them single precision, too.

(This can also improve performance, but that's not the reason to do it; the reason to do it is because it will make your code more correct).