22
votes

Depending on this question Floating point division vs floating point multiplication. Division is slower than multiplication due to some reasons.

Will the compiler, usually, replace division by multiplication if it is possibe?

For example:

float a;
// During runtime a=5.4f
float b = a/10.f;

Will it be:

float a;
// During runtime a=5.4f
float b = a*0.1f;

If it is considered a compiler dependable question, I am using VS2013 default compiler. However, it would be nice if I got a generic answer (theoretical validity of this optimization)

1
Wouldn't the compiler have to do a division in order to be able to multiply by the reciprocal?NathanOliver
This is not case included under "if possible", this is a case where it's not possible unless a loss of accuracy is accepted. So, hopefully only when compiling with a flag that specifically allows it.harold
goo.gl/AV8MlT Doesn't look like the compiler would optimize here.Simon Kraemer
You can look at assembly output in MSVC++ with fp:fast option: msdn.microsoft.com/en-us/library/e7s85ffb.aspxSerge Rogatch
I know this is for VS2013, but for the interest of GCC users: in GCC, the flag that specifically enables this particular optimization is -freciprocal-math, which is also automatically enabled when selecting either -funsafe-math-optimizations, -ffast-math or -Ofast. See gcc.gnu.org/onlinedocs/gcc-4.9.1/gcc/Optimize-Options.htmlPedro Gimeno

1 Answers

21
votes

No, the compiler is not allowed to do that for the general case: the two operations could produce results that are not bit-identical due to the representation error of the reciprocal.

In your example, 0.1 does not have an exact representation as float. This causes the results of multiplication by 0.1 and division by 10 to differ:

float f = 21736517;
float a = f / 10.f;
float b = f * 0.1f;
cout << (a == b) << endl; // Prints zero

Demo.

Note: As njuffa correctly notes in the comment below, there are situations when the compiler could make some optimizations for a wide set of numbers, as described in this paper. For example, multiplying or dividing by a power of two is equivalent to addition to the exponent portion of the IEEE-754 float representation.