Сравнение типов данных с плавающей запятой и типа double в задаче C - PullRequest
18 голосов
/ 17 февраля 2011

При использовании типа данных double или float в приложении для iPhone у меня возникают проблемы со сравнениями «> =» и «<=», потому что, когда переменной присваивается число, введенное с одним десятичным знаком, например 4.2, float или double, используемые в сравнении, на самом деле могут иметь значение, например 4.1999998092651367. Из-за этой разницы сравнение, такое как "> = 4.2", является ложным, а не истинным. Как я могу избежать этой проблемы?

1 Ответ

63 голосов
/ 17 февраля 2011

, когда переменной присваивается число, введенное с одним десятичным разрядом, например, 4.2, значение с плавающей запятой или двойное число, используемое в сравнении, на самом деле может иметь значение, например 4.1999998092651367

Не может . будет .Чтобы быть конкретным:

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

Проблема возникает, когда вы пишете что-то вроде:

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

f точно 4.19999980926513671875, но вы сравниваете его с литерал двойной точности"4.2", который имеет значение 4.20000000000000017763568394002504646778106689453125, поэтому сравнение не удается.Если вместо этого вы сравниваете с литералом одинарной точности "4.2f":

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

, сравнение успешно, потому что значения в точности равны.Плавающая точка сложна, но она полностью детерминирована;одна из самых простых вещей, которую вы можете сделать, чтобы сделать ее более интуитивной, это не смешивать точность.Если вы работаете с float, убедитесь, что все ваши литералы имеют суффикс f, чтобы сделать их также с одинарной точностью.

(Это также может улучшить производительность, но это не причина для этогоэто; причина сделать это потому, что это сделает ваш код более правильным).

...