I'm running CodeBlocks 17.12, it's never given me any problems (I've only been using it for a semester though) and now all of a sudden it's giving me this weird off by 1 error. The code included should print 100 but instead, it prints 99. After some troubleshooting, I discovered that taking away "using namespace std" and instead using the shorthand "std::" fixes this error. Would like any input as to what could be the problem here. Thanks.
//Gives an off by one error
#include <iostream>
#include <cmath>
usingnamespace std;
int main()
{
int x = pow(10,2);
cout << x;
}
//Doesn't give an off by one error
/*
#include <iostream>
#include <cmath>
int main()
{
int x = pow(10,2);
std::cout << x;
}
*/
pow works with floating-point numbers and as always when working with floating-point numbers rounding errors has to be expected.
pow(10, 2) returns a double with a value that is very close to 100, but not necessarily exactly 100. If it is 99.999....something you will get 99 when converting it to an int. A solution might be to change x to a double. If x is supposed to be an int you could instead round the number to the closest integer before converting it to an int.
pow is slower than it needs to be for ints because it handles floats, and it can have roundoff problems. Many programmers write their own integer power routine for speed & precision both.
for 0-3 powers, you may be better off just doing x*x inline. For 4+ go ahead and write a function.
And what version of the compiler, and what optimization level is enabled.
I'm running the MinGW distribution of g++ (GCC) 7.2.0, and get 100 for both programs, with or without -O3.
The codeblocks-17.12mingw-setup.exe file includes additionally the GCC/G++ compiler and GDB debugger from TDM-GCC (version 5.1.0, 32 bit, SJLJ)
Assuming Windows, that runs TDM-GCC 5.1.0, which is from 2015. (Perhaps not technically a "bug", due to the inherent nature of floating-point, but less-than-optimal behavior).
Compilers like GCC implement their own versions of pow which they treat special. Perhaps because you didn't specify that you were using std::pow, it used the compiler's internal pow, which had a slightly different implementation. I don't actually know.
@Peter87 I was aware of how the pow function works and how it uses floating-point numbers. What's rather strange about this is that it doesn't output the same response in other compilers (www.onlinegdb.com, cpp.sh, Visual Studio).
@jonnin For my particular program I was writing I only need a power of two so I did end up doing what you suggested, just found intriguing as to why this was happening.
@Ganago @dutch After 30 minutes of trying to find where to type the -S flag command I've admitted defeat, I'm pretty new to programming. Even using std::pow I get 99. I was initially thinking it could be due to the nature of Peter's comment (integers rounding down to nearest whole number), but then again it works correctly for other compilers.
I don't know what the compiler is deciding behind the scenes in your case, but the key takeaway here is: Be aware that when you're dealing with floating-point numbers, the result may not be exactly what you expect. So when in doubt, if you're converting a floating-point to an integer, round it.
The interesting thing here is that he seems to be getting two different versions of pow. One is std::pow, which he gets if he uses namespace std or puts std:: in front of pow. That version returns 99.9... for an answer. The other is ::pow, which apparently returns 100.0... for an answer.
So presumably this version will print 100.
1 2 3 4 5 6 7 8 9
#include <iostream>
#include <cmath>
usingnamespace std;
int main()
{
int x = ::pow(10,2); // use global pow (not std::pow)
cout << x << '\n';
}
In that case, the assembly may show no difference since the difference is that they link to different pow functions.