Ответ 1
Т.Л., д - р это связано с очень глубокими деталями, как NaN
представлены в двоичной системе. Вы можете обойти это, используя digest(.,ascii=TRUE)
...
В продолжение ответа @Jozef: обратите внимание на жирные цифры...
> base::serialize(Inf-Inf,connection=NULL) [1] 58 0a 00 00 00 03 00 03 06 00 00 03 05 00 00 00 00 05 55 54 46 2d 38 00 00 [26] 00 0e 00 00 00 01 ff f8 00 00 00 00 00 00 > base::serialize(NaN,connection=NULL) [1] 58 0a 00 00 00 03 00 03 06 00 00 03 05 00 00 00 00 05 55 54 46 2d 38 00 00 [26] 00 0e 00 00 00 01 7f f8 00 00 00 00 00 00
Кроме того, используя pryr::bytes()
...
> bytes(NaN)
[1] "7F F8 00 00 00 00 00 00"
> bytes(Inf-Inf)
[1] "FF F8 00 00 00 00 00 00"
Статья в Википедии о формате с плавающей запятой /NaNs говорит:
Некоторые операции с арифметикой с плавающей точкой недопустимы, например, получение квадратного корня из отрицательного числа. Достижение недопустимого результата называется исключением с плавающей точкой. Исключительный результат представлен специальным кодом, называемым NaN, для "Не числа". Все NaNs в IEEE 754-1985 имеют этот формат:
- знак = 0 или 1.
- смещенная экспонента = все 1 бит.
- фракция = все, кроме всех 0 бит (поскольку все 0 бит представляют бесконечность).
Знак является первым битом; показатель степени - следующие 11 битов; дробь это последние 52 бита. При переводе первых четырех шестнадцатеричных цифр, приведенных выше, в двоичную Inf-Inf
, Inf-Inf
равен 1111 1111 1111 0100
(знак = 1; экспонента - все единицы, как требуется; дробь начинается с 0100
), тогда как NaN
- 0111 1111 1111 0100
(то же самое, но с знак = 0).
Чтобы понять, почему Inf-Inf
заканчивается знаковым битом 1, а NaN
- знаковым битом 0, вам, вероятно, придется глубже изучить способ реализации арифметики с плавающей запятой на этой платформе...
Возможно, стоит поднять вопрос об этом в репозитории GitHub; Я не могу придумать изящного способа сделать это, но кажется разумным, что объекты, для которых identical(x,y)
равен TRUE
в R, должны иметь идентичные хеш-коды... Обратите внимание, что identical()
специально игнорирует эти различия в битовых комбинациях через single.NA
(по умолчанию TRUE
):
single.NA: логическое указание, если концептуально существует только один числовой "NA и один" NaN; 'single.NA = FALSE различает битовые комбинации.
В коде C похоже, что R просто использует оператор C !=
Для сравнения значений NaN
если не включено побитовое сравнение, и в этом случае он явно проверяет равенство ячеек памяти: см. Здесь. То есть оператор сравнения C, по-видимому, рассматривает различные виды значений NaN
как эквивалентные...