Если вы хотите обрабатывать весь диапазон возможных значений A
и B
, то вам нужно быть немного осторожнее, но на самом деле это не так уж сложно.
Предложение использования a*b*b < 1.
является хорошим; если b
настолько мал, что a*b*b
падает до нуля, то a
обязательно меньше, чем 1./(b*b)
. И наоборот, если b
настолько велико, что a*b*b
переполняется до бесконечности, то условие (правильно) не будет выполнено. ( Potatoswatter правильно указывает в комментарии к другому сообщению, что это не работает правильно, если вы напишите b*b*a
, потому что b*b
может переполниться до бесконечности, даже если условие должно будет верно, если a
окажется ненормальным. Однако в C умножение ассоциируется слева направо, так что это не проблема, если вы напишите его a*b*b
и ваша платформа придерживается разумной числовой модели.)
Поскольку вы знаете априори , что a
и b
являются положительными числами, a*b*b
не может сгенерировать NaN, поэтому вам не нужно беспокоиться об этом условии. Переполнение и переполнение являются единственно возможными нарушениями, и мы уже учли их. Если вам нужно поддержать случай, когда a
или b
могут быть равны нулю или бесконечности, вам нужно быть более осторожным.
Чтобы ответить на ваши прямые вопросы: (ответы предполагают арифметику IEEE-754)
Может ли 1 / X быть бесконечностью, если X больше нуля (но мало)?
Да! Если x - это небольшое положительное ненормальное значение, то 1/x
может переполниться и привести к бесконечности. Например, при двойной точности в режиме округления по умолчанию 1 / 0x1.0p-1024
будет переполнен.
Может ли X * X быть нулем, если Х больше нуля?
Да! С двойной точностью в режиме округления по умолчанию все значения x меньше 0x1.0p-538
(то есть 2**-578
в шестнадцатеричном формате C99) или около того имеют это свойство.
Будет ли сравнение с бесконечностью работать так, как я ожидал?
Да! Это одна из лучших функций IEEE-754.