В большинстве приложений будет какое-то значение, ниже которого число с плавающей запятой "может также быть" нулем. Например, рассмотрим что-то вроде:
float intensity(float dx, float dy)
{
float result = 1/(dx*dx + dy*dy);
if (result > 65535.0f) result = 65535.0f;
return result;
}
Если делитель меньше 1 / 65535.0f, то в случаях, когда расстояние не равно нулю, функция должна возвращать 65535.0f независимо от фактического значения делителя, и такое поведение, вероятно, будет полезно, даже если оно это ноль. Таким образом, функция может быть переписана как:
float intensity(float dx, float dy)
{
float distSq = dx*dx + dy*dy;
if (distSq <= (1.0f/65535.0f))
return 65535.0;
else
return 1/distSq;
}
Обратите внимание, что обработка кода в этом случае может быть очень несовершенной. Хотя это не является проблемой для 65535.0f, в частности, могут быть случаи, когда distSq
точно равно обратной величине максимального значения, но обратная величина меньше максимальной величины. Например, если максимальное значение равно 46470.0f, а distSq
равно 0,0000215238924f, правильный результат будет 46459.9961f, но функция вернет 46470.0f. Такие вопросы вряд ли будут создавать проблемы на практике, но нужно знать о них. Обратите внимание, что если для сравнения использовалось значение «меньше», чем «меньше или меньше или равно», а максимум был 46590,0f, значение distSq
0,0000214642932f дало бы результат 46589,0039, что превышает максимум.
Между прочим, во многих системах стоимость вычисления приблизительной обратной величины делителя и умножения на дивиденд может быть намного дешевле, чем стоимость выполнения деления с плавающей запятой. Такой подход может быть полезен во многих ситуациях, когда его точность будет адекватной.