У меня есть некоторые места в моем коде, где я хочу заверить, что разделение двух произвольных чисел с плавающей запятой (32-разрядная одинарная точность) не будет переполняться. Целевой/компилятор не гарантирует (явно) хорошую обработку -INF/INF и (не полностью гарантирует IEEE 754 для исключительных значений - (возможно, undefined) - и цель может измениться). Также я не могу сделать предположения о сохранении входов для этих нескольких особых мест, и я связан с стандартными библиотеками C90.
Я прочитал Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой, но, честно говоря, я немного потерялся.
Итак... Я хочу спросить сообщество, если следующий фрагмент кода будет делать трюк, и если есть более эффективные/быстрые/exact/correcter способы сделать это:
#define SIGN_F(val) ((val >= 0.0f)? 1.0f : -1.0f)
float32_t safedivf(float32_t num, float32_t denum)
{
const float32_t abs_denum = fabs(denum);
if((abs_denum < 1.0f) && ((abs_denum * FLT_MAX) <= (float32_t)fabs(num))
return SIGN_F(denum) * SIGN_F(num) * FLT_MAX;
else
return num / denum;
}
Изменить: Изменено ((abs_denum * FLT_MAX) < (float32_t)fabs(num))
до ((abs_denum * FLT_MAX) <= (float32_t)fabs(num))
, как это рекомендовал Паскаль Куок.