Реализация деления с одинарной точностью как умножение с двойной точностью
Для компилятора C99, реализующего точную арифметику IEEE 754, сделайте значения,f
divisor
типаfloat
существуют такие что?f / divisor != (float)(f * (1.0 / divisor))
РЕДАКТИРОВАТЬ: "реализуя точную арифметику IEEE 754 » Я имею в виду компилятор, который по праву определяет FLT_EVAL_METHOD как 0.
контекстКомпилятор C, который обеспечивает IEEE 754-совместимое число с плавающей точкой, может заменить деление с одинарной точностью на константу только умножением с одинарной точностью на обратное, если само обратное представимо в точности как a.float
На практике это происходит только для двух сил. Так что программист Алекс может быть уверен, чтоf / 2.0f
будет скомпилировано, как если бы это былоf * 0.5f
, но если для Алекса приемлемо умножить на0.10f
вместо деления на 10 Алекс должен выразить это, записав умножение в программе или используя опцию компилятора, такую как GCC.-ffast-math
Этот вопрос касается преобразования деления с одинарной точностью в умножение с двойной точностью. Всегда ли это дает правильно округленный результат? Есть ли вероятность, что это может быть дешевле, и, таким образом, это может быть оптимизация, которую могут сделать компиляторы (даже без-ffast-math
)?
Я сравнил(float)(f * 0.10)
а такжеf / 10.0f
для всех значений одинарной точностиf
между 1 и 2, не найдя контрпримеров. Это должно охватывать все подразделения нормальногоfloat
с нормальным результатом.
Затем я обобщил тест на все делители с помощью программы ниже:
#include
#include
#include
int main(void){
for (float divisor = 1.0; divisor != 2.0; divisor = nextafterf(divisor, 2.0))
{
double factor = 1.0 / divisor; // double-precision inverse
for (float f = 1.0; f != 2.0; f = nextafterf(f, 2.0))
{
float cr = f / divisor;
float opt = f * factor; // double-precision multiplication
if (cr != opt)
printf("For divisor=%a, f=%a, f/divisor=%a but (float)(f*factor)=%a\n",
divisor, f, cr, opt);
}
}
}
Пространство поиска достаточно велико, чтобы сделать это интересным (246). Программа в настоящее время работает. Может кто-нибудь сказать мне, напечатает ли он что-нибудь, возможно, с объяснением, почему или почему, до того, как это закончится?