Как оператор C == определяет, равны ли два значения с плавающей запятой?

Сегодня я отслеживал, почему моя программа выдает некоторые неожиданные ошибки несоответствия контрольной суммы в некотором написанном мной коде, который сериализует и десериализует значения с плавающей запятой IEEE-754 в формате, который включает 32-битное значение контрольной суммы (которое вычисляется путем выполнения алгоритма типа CRC над байтами массива с плавающей запятой

Немного поцарапав голову, я понял, что проблема в том, что 0.0f и -0.0f имеют разные битовые шаблоны (0x00000000 и 0x00000080 (с прямым порядком байтов), соответственно), но они считаются эквивалентными Оператор равенства C ++. Итак, ошибки несоответствия контрольной суммы произошли из-за того, что мой алгоритм вычисления контрольной суммы уловил разницу между этими двумя битовыми шаблонами, в то время как некоторые другие части моей кодовой базы (которые используют проверку равенства с плавающей запятой, а не рассматривают значения побайтно. byte) не проводил такого различия.

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

Но это заставило меня задуматься, есть ли другие плавающие запятой IEEE-754 значения, которые считаются равными (согласно оператору C ==), но имеют разные битовые шаблоны? Или, говоря другими словами, как именно оператор == определяет, равны ли два значения с плавающей запятой? Я новичок, хотя он делал что-то вроде memcmp () в их битовых шаблонах, но очевидно, что это более тонко, чем это.

Вот пример кода того, что я имею в виду, на случай, если я не понял выше.

#include <stdio.h>

static void PrintFloatBytes(const char * title, float f)
{
   printf("Byte-representation of [%s] is: ", title);
   const unsigned char * p = (const unsigned char *) &f;
   for (int i=0; i<sizeof(f); i++) printf("%02x ", p[i]);
   printf("\n");
}

int main(int argc, char ** argv)
{
   const float pzero = -0.0f;
   const float nzero = +0.0f;
   PrintFloatBytes("pzero", pzero);
   PrintFloatBytes("nzero", nzero);
   printf("Is pzero equal to nzero?  %s\n", (pzero==nzero)?"Yes":"No");
   return 0;
}
7
задан mskfisher 10 May 2012 в 17:16
поделиться