Сравнение чисел с плавающей запятой в C

У меня есть double который печатает как 0.000000 и я пытаюсь сравнить его с 0.0f , безуспешно. Почему здесь разница? Какой самый надежный способ определить, равен ли ваш двойник нулю?

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

     fabs(d) < 0.0000005 

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

    Если вы хотите лучше понять, какое значение у вас есть, попробуйте выполнить печать с %g вместо %f .

    Вы можете сделать диапазон. Например -0.00001 <= x <= 0.00001

    Это фундаментальная проблема с арифметикой с плавающей запятой на современных компьютерах. Они по своей природе неточны и не могут быть надежно сопоставлены. Например, язык ML явно запрещает сравнение равенства для реальных типов, потому что он считается слишком опасным. См. Также отличную (если немного длинную и математически ориентированную) статью Дэвида Голдберга по этой теме.

    Edit: tl; dr: вы можете делать это неправильно.

    Кроме того, часто забываемыми функциями числа с плавающей запятой являются денормализованные числа. Это числа, которые имеют минимальный показатель, но не подходят в диапазоне 0,5-1.

    Эти числа ниже FLT_MIN для float и DBL_MIN для double.

    Общей ошибкой с использованием порога является сравнение двух значений или использование FLT_MIN / DBL_MIN в качестве предела.

    Например, это приведет к нелогичному результату (если вы не знаете о денормалах):

     bool areDifferent(float a, float b) { if (a == b) return false; // Or also: if ((a - b) == FLT_MIN) return true; } // What is the output of areDifferent(val, val + FLT_MIN * 0.5f) ? // true, not false, even if adding half the "minimum value". 

    Денормалы также обычно подразумевают потерю производительности при вычислении. Тем не менее, вы не можете их отключить, иначе такой код может генерировать исключение с плавающей запятой DIVIDE BY ZERO (если включено):

     float getInverse(float a, float b) { if (a != b) return 1.0f / (ab); // With denormals disabled, a != b can be true, but (a - b) can still be denormals, it'll rounded to 0 and throw the exception return FLT_MAX; } 
    Interesting Posts

    Ошибка менеджера местоположений: (ошибка KCLErrorDomain 0)

    Как мне нажать Ctrl + Alt + Удалить в VirtualBox?

    Как добавить дополнительные коннекторы (клей) в форму в слове или powerpoint?

    Есть ли недостатки в использовании UPX для сжатия исполняемого файла Windows?

    Как использовать eyefinity

    x86 Расчет AX с учетом AH и AL?

    Есть ли способ установить приоритет процесса в Mac OS X?

    Удаление RAID 1 (зеркальное отображение) и сохранение данных на обоих дисках

    Как работает ключевое слово «final» в Java? (Я все еще могу изменить объект.)

    На PCIe 1.0 64-разрядная графическая карта может быть совместима с 32-разрядной ОС (Windows 7 32bits)

    Когда следует использовать std :: move для возвращаемого значения функции?

    Глобальные переменные в Java

    Android – внедрение startForeground для службы?

    visual c ++: # включить файлы из других проектов в одном решении

    java.lang.IllegalStateException: указанный дочерний элемент уже имеет родителя

    Давайте будем гением компьютера.