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?
当使用双或浮点数据类型在一个iPhone应用程序,我遇到问题“> =”、“< =”比较,因为当一个变量被分配一个号码进入一个小数位,如4.2中,使用的浮点数和双精度数比较实际值如4.1999998092651367。由于这种差异,像“>= 4.2”这样的比较是假的而不是真的。我怎样才能避免这个问题呢?
1 个解决方案
#1
63
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
当一个变量被赋值为一个小数时,例如4.2,比较中使用的浮点数或双精度数实际上可能有一个值,比如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":
f正好是4.19999980926513671875,但是您将它与双精度文字“4.2”进行比较,后者的值是4.20000000000000000001776356839400400467786689453125,所以比较失败。如果你把它与单精度文字“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.
比较成功,因为值完全相等。浮点是复杂的,但完全是确定性的;要使它更直观,最简单的事情之一就是不要混淆精确。如果使用浮点数,请确保所有的字符都以f结尾,以使它们也具有单一的精度。
(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).
(这也可以提高性能,但这不是这么做的原因;这样做的原因是它将使您的代码更加正确)。
#1
63
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
当一个变量被赋值为一个小数时,例如4.2,比较中使用的浮点数或双精度数实际上可能有一个值,比如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":
f正好是4.19999980926513671875,但是您将它与双精度文字“4.2”进行比较,后者的值是4.20000000000000000001776356839400400467786689453125,所以比较失败。如果你把它与单精度文字“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.
比较成功,因为值完全相等。浮点是复杂的,但完全是确定性的;要使它更直观,最简单的事情之一就是不要混淆精确。如果使用浮点数,请确保所有的字符都以f结尾,以使它们也具有单一的精度。
(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).
(这也可以提高性能,但这不是这么做的原因;这样做的原因是它将使您的代码更加正确)。