Почему нельзя сравнивать типы с плавающей запятой, используя функцию memcmp()?

bool floatcmp(const float a, const float b)
{
 const void *p = (void*)&a;
 const void *q = (void*)&b;
 if (memcmp(p, q, sizeof(float)) == 0)
 return true;
 return false;
}

Пример кода выше, на странице man говорится, что memcmp(x,y)==0 не означает, что x==y и типы с плавающей запятой часто имеют значение NaN ('не число) со свойством NaN == NaN ложно. Но я изменяю тип на void *, и я думаю, что компилятор не знает, a это число с плавающей точкой.

1 ответ

Их можно сравнить с memcmp() - ОДНАКО, что сравнение является побайтовым сравнением, которое не имеет отношения к численной интерпретации этих байтов. Пока все значения являются неспецифическими (различные вкусы Inf/NaN и т.д.) И нормализуются, он должен быть надежным тестом для точного равенства, но нет никаких гарантий этого, и нет никакой гарантии, что он будет быстрее чем обычный точный тест равенства a == b (который, кстати, имеет ту же самую озабоченность, что большинство дробных чисел не является точно представимым в плавающей точке) - поэтому два числа, которые должны быть равны, не представлены таким образом их плавающим точечные аппроксимации.

EDIT: Мне кажется, что сортировка может быть единственным местом, где точное сравнение может иметь значение для чисел с плавающей запятой, - если вы скажете qsort, что числа "равны" в "хорошо, их различие меньше, чем 2e ', то сортировка поместит их в некоторый неопределенный порядок, поэтому кажется, что порядок, заданный точным тестом равенства, должен быть таким же хорошим, как и любой другой порядок.

licensed under cc by-sa 3.0 with attribution.