Проблема с плавающей запятой в R?

Возможный дубликат:
Почему эти цифры не равны?

Ниже выражение, которое оценивается до 0,1, считается больше 0,1.

> round(1740/600,0) - 1740/600
[1] 0.1
> (round(1740/600,0) - 1740/600) <= 0.1
[1] FALSE //???!!???
> (round(1740/600,0) - 1740/600) <= 0.1000000000000000000000000000000000000001
[1] TRUE

Думая, что проблема может быть вызвана округлением, я попробовал это с тем же результатом:

> 3 - 2.9
[1] 0.1
> (3 - 2.9) <=0.1
[1] FALSE

Итак, что дает и как я могу исправить это, не вымачивая отсечку?

Ответ 1

В Руководство по плавающей запятой:

Почему не мои цифры, например, 0,1 + 0,2, составляют хороший раунд 0,3 и вместо этого я получаю странный результат, например 0.30000000000000004?

Поскольку внутренне компьютеры используют формат (двоичный с плавающей запятой) которые не могут точно представлять число, например 0,1, 0,2 или 0,3.

Когда код компилируется или интерпретируется, ваш "0,1" уже округленное до ближайшего номера в этом формате, что приводит к небольшому ошибка округления даже до того, как произойдет расчет.

Что можно сделать, чтобы избежать этой проблемы?

Это зависит от того, какие вычисления вы делаете.

  • Если вам действительно нужны ваши результаты, чтобы точно добавить, особенно когда вы работаете с деньгами: используйте специальный десятичный тип данных.
  • Если вы просто не хотите видеть все эти дополнительные десятичные знаки: просто отформатируйте результат округляется до фиксированного числа десятичных знаков при его отображении.
  • Если у вас нет десятичного типа данных, альтернативой является работа с целыми числами, например. делать денежные расчеты целиком в центах. Но это больше работы и имеет некоторые недостатки.

Ответ 2

Есть R-функции, которые автоматически принимают разумные подходы к "проблеме равенства":

> (3 - 2.9) <=0.1
#[1] FALSE

> all.equal( (3 - 2.9) , 0.1)
#[1] TRUE

Он использует sqrt из R наименьшего числа положительных чисел с плавающей запятой в качестве порогового значения по умолчанию, поэтому он обрабатывает ошибки умножения и разложения. Заканчивается около 1е-08