Implementando divisão de precisão simples como multiplicação de precisão dupla

Questão

Para um compilador C99 implementando a aritmética IEEE 754 exata, façaf, divisor do tipofloat existem tais quef / divisor != (float)(f * (1.0 / divisor))?

EDIT: Por "implementação exata IEEE 754 aritmética" refiro-me a um compilador que legitimamente define FLT_EVAL_METHOD como 0.

Contexto

Um compilador C que fornece ponto flutuante compatível com IEEE 754 só pode substituir uma divisão de precisão simples por uma constante por uma multiplicação de precisão simples pelo inverso se o inverso for ele próprio representável exatamente como umfloat.

Na prática, isso só acontece com poderes de dois. Então, um programador, Alex, pode estar confiante de quef / 2.0f será compilado como se tivesse sidof * 0.5f, mas se é aceitável para Alex multiplicar por0.10f em vez de dividir por 10, Alex deve expressá-lo escrevendo a multiplicação no programa, ou usando uma opção de compilador como o GCC-ffast-math.

Esta questão é sobre transformar uma divisão de precisão única em uma multiplicação de precisão dupla. Produz sempre o resultado corretamente arredondado? Existe uma chance de que poderia ser mais barato e, portanto, uma otimização que os compiladores podem fazer (mesmo sem-ffast-math)

Eu comparei(float)(f * 0.10) ef / 10.0f para todos os valores de precisão simplesf entre 1 e 2, sem encontrar qualquer contra-exemplo. Isto deve cobrir todas as divisões defloats produzindo um resultado normal.

Então eu generalizei o teste para todos os divisores com o programa abaixo:

#include <float.h>
#include <math.h>
#include <stdio.h>

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);
        }
    }
}

O espaço de busca é grande o suficiente para tornar isso interessante (246). O programa está sendo executado no momento. Alguém pode me dizer se vai imprimir alguma coisa, talvez com uma explicação por que ou por que não, antes de terminar?

questionAnswers(3)

yourAnswerToTheQuestion