Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctness of cmath's pow() in GCC

Tags:

c++

math

gcc

g++

Code [GCC, compiled with -O2 flag]

int main()
{
    vector< vector<int> > matrixa(8);
    int ff = 5;
    int s = pow(ff, matrixa.size());
    int ss = pow(double(ff), int(matrixa.size()));
    vector< vector<int> > comb(s);
    cout << ff << "^" << matrixa.size() << " = " << s << endl;
    cout << ss << endl;
    return 0;
}

Output

5^8 = 390624
390625

I'm wondering why s = 390624 when it should be 390625. If I compile the code without -O2 flag, then s = 390625. Also, the casting for ss seems to correct the problem.

What's going on?

My OS is Windows 7 Ultimate x64. Not sure about the GCC version, it comes with Code::Blocks 10.05.

like image 936
Donotalo Avatar asked Dec 20 '22 19:12

Donotalo


2 Answers

Because floating-point arithmetic is not perfect and when you do

int s = pow(ff, matrixa.size());

the result of pow is actually something more like 390624.99999 and when you truncate it to int it effectively is flattened down to 390624. If you expect an integer value there (a floating-point with .0 fractional part), you should probably round the result of pow.

like image 97
Desmond Hume Avatar answered Dec 24 '22 00:12

Desmond Hume


Try assigning the result to a double and output it (with possible bigger std::setprecision) settings. You will see that due to rounding errors, the value will be something like 390624.99999999999 (or similar).

Casting to an int truncates the fractional part, thus leaving you with 390624. Use std::round to get the desired result.

like image 38
PlasmaHH Avatar answered Dec 24 '22 00:12

PlasmaHH