Сравните поплавки в R - PullRequest
       69

Сравните поплавки в R

0 голосов
/ 22 апреля 2020

Отказ от ответственности

Я не был уверен, стоит ли публиковать это здесь или на CV , но после прочтения, что находится на topi c на CV Я думаю, что это больше R специфика c, чем чисто статистическая. Таким образом, я разместил это здесь.

Задача

Ссылаясь на ?.Machine

double.eps
наименьшее положительное значение с плавающей точкой номер точки x такой, что 1 + x != 1. Это равно double.base ^ ulp.digits, если либо double.base равно 2, либо double.rounding равно 0; в противном случае это (double.base ^ double.ulp.digits) / 2. Обычно 2.220446e-16.

Таким образом, я предполагаю, что all.equal(1 + .Machine$double.eps, 1.0) возвращает FALSE. Что это не так. Читая do c из all.equal, я вижу, что допуск по умолчанию равен .Machine$double.eps ^ 0.5.

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

isTRUE(all.equal(1.0 + .Machine$double.eps, 1.0, tolerance = .Machine$double.eps)) # TRUE
isTRUE(all.equal(1.0 - .Machine$double.eps, 1.0, tolerance = .Machine$double.eps)) # FALSE
isTRUE(all.equal(0.9 + .Machine$double.eps, 0.9, tolerance = .Machine$double.eps)) # FALSE
isTRUE(all.equal(2.0 + .Machine$double.eps, 2.0, tolerance = .Machine$double.eps)) # TRUE

Таким образом, all.equal правильно выбирает только различия для чисел ниже 1.

Последнее объяснение, которое я могу придумать, состоит в том, что all.equal выглядит по шкале относительных разностей по умолчанию, поэтому я попытался отменить это поведение также безуспешно:

isTRUE(all.equal(1.0 + .Machine$double.eps, 1.0, 
                 tolerance = .Machine$double.eps, scale = 1)) # TRUE

По-видимому, у меня есть огромное недопонимание того, как числа с плавающей запятой работают в R, что приводит меня к этим

Вопросы

  • Как правильно сравнить 2 числа в R с "максимальной" (относительно точности с плавающей запятой) точностью?
  • Почему результаты all.equal различны для чисел ниже и выше 1?
  • [Бонусный вопрос]: что является рациональным для использования .Machine$double.eps ^ .5 в качестве допуска по умолчанию вместо не квадратной версии? Это просто немного расслабить тест?

1 Ответ

1 голос
/ 22 апреля 2020

.Machine$double.eps - это разница между 1 и наименьшим представимым значением, превышающим 1. Разница между 0,1 и наименьшим представимым значением, превышающим 0,1, меньше .Machine$double.eps, а разница между 100 и наименьшим представимым значением больше, чем 100 больше .Machine$double.eps. Взгляните на: Какой правильный / стандартный способ проверить, меньше ли разница, чем точность станка? .

.Machine$double.eps равно

.Machine$double.eps
[1] 2.220446e-16

Когда вы Выполните вычисления, чтобы значения для интерна были примерно равны:

print(1.0 + .Machine$double.eps, 20)
#[1] 1.000000000000000222
print(1.0 - .Machine$double.eps, 20)
#[1] 0.99999999999999977796
print(0.9 + .Machine$double.eps, 20)
#[1] 0.90000000000000024425
print(2.0 + .Machine$double.eps, 20)
#[1] 2

Использование tolerance = .Machine$double.eps all.equal возвращает TRUE или FALSE в зависимости от того, является ли разница сохраненных значений интерна больше или не больше tolerance.

Для сравнения 2 чисел в R, если они хранятся внутри, используйте ==.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...