Два теоретически идентичных кода не генерируют одинаковый вывод - PullRequest
4 голосов
/ 22 января 2020

Я пытаюсь запустить процедуру в R , включая репликацию случайного эксперимента. Я столкнулся с ошибками в измерении вывода, что привело меня к обнаружению следующей особенности:

length(replicate(100 - 100*8 / 10, 4))
# 20
length(replicate(100 *(1- 8/ 10), 4))
# 19

В качестве проверки работоспособности я запустил строки кода, чтобы убедиться, что выражения в первом аргументе replicate выдает тот же результат.

100 - 100*8 / 10
# 20
100 *(1- 8/ 10)
# 20

Мне было интересно, сталкиваются ли люди с такой же проблемой. Что я действительно хочу знать, так это то, почему это происходит?

Примечание: я осознаю разницу между rep и replicate, и моя рутина требует последнего, а не первый.

Ответы [ 3 ]

4 голосов
/ 22 января 2020

Это не совсем то же самое

(100 *(1- 8/ 10)) == 20
#[1] FALSE

(100 - 100*8 / 10) == 20
#[1] TRUE

, потому что

20 - (100 *(1- 8/ 10))
#[1] 3.552714e-15

и n в ?replicate является целым числом

n - целое число: количество копий.

Преобразование этого вывода в integer floor с в 19

as.integer((100 *(1- 8/ 10)))
#[1] 19

floor((100 *(1- 8/ 10)))
#[1] 19

Один из вариантов - обернуть с ceiling

length(replicate(ceiling(100 *(1- 8/ 10)), 4))
#[1] 20
2 голосов
/ 22 января 2020

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

В вашем случае эта проблема представляется как 1- 8/10 не совпадает с 0.2:

identical(    8/10, 0.8 )   # TRUE
identical( 1- 8/10, 0.2 )   # FALSE

Причина root заключается в том, что невозможно точно представить 0,8 и 0,2 в двоичном виде с конечным числом битов. В памяти эти значения эффективно округляются до ближайшего 32-разрядного или 64-разрядного двоичного представления. Это округление затем каскадно проходит арифметические операции c.

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

Это очень распространенная арифметическая проблема с плавающей точкой c, присутствующая во многих языках программирования. Некоторое дальнейшее чтение по топи c можно найти здесь.

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