The other way of answering this is to say that you did not get one "wrong" answer and two "right" answers. You actually got three "right" answers, where "right" means, "as good as could have been expected".
Type float
only gives you about 7 decimal digits of precision. So for numbers in the range of 1000, that's three places past the decimal. So change the program like this:
printf("%.3f\n", 0.0001f * 10000000.0f);
printf("%.3f\n", 0.001f * 1000000.0f);
printf("%.3f\n", 0.01f * 100000.0f);
The output is:
1000.000
1000.000
1000.000
No discrepancy, all answers apparently correct.
Or, do it in exponential notation, with one digit before the decimal and 6 after.
printf("%.6e\n", 0.0001f * 10000000.0f);
printf("%.6e\n", 0.001f * 1000000.0f);
printf("%.6e\n", 0.01f * 100000.0f);
gives
1.000000e+03
1.000000e+03
1.000000e+03
Again, all answers the same.
This might seem like "cheating": we happen to know there's some "interesting" things going on in the digits off to the right of what we can see, so isn't it wrong to suppress them in this way, and make it look like all the answers were the same? I'm not going to answer that question, other than to point out that when you're doing floating-point work, there's almost always something off there to the right, that you're rounding off and suppressing -- it's just a matter of degree.