Реализация деления с одинарной точностью как умножение с двойной точностью

Вопрос

Для компилятора C99, реализующего точную арифметику IEEE 754, сделайте значения,fdivisor типа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). Программа в настоящее время работает. Может кто-нибудь сказать мне, напечатает ли он что-нибудь, возможно, с объяснением, почему или почему, до того, как это закончится?

Ответы на вопрос(3)

Ваш ответ на вопрос