Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double to int implicit conversion in mingw32

Tags:

c

mingw32

I can't explain the behaviour of the following program (compiled with gcc on mingw 32 bits). I'm aware of the possible precision loss when implicitly converting from double to int, but I would expect the two cases to give the same output since it is doing the exact same operations. Why are the two outputs different?

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

int main()
{
    int table[3] = {2, 3, 4};
    int i, N;

    N = 0;
    N += table[0] * pow(100, 0);
    N += table[1] * pow(100, 1);
    N += table[2] * pow(100, 2);
    printf("%d\n", N);

    N = 0;
    for(i = 0; i < 3; i++)
        N += table[i] * pow(100, i);
    printf("%d\n", N);

    return 0;
}

//output: 
40302
40300
like image 992
Étienne Avatar asked Dec 07 '14 16:12

Étienne


1 Answers

With pow(100, 0) pow(100, 1) and pow(100, 2) the compiler replaces the function calls with constants (1, 100, 10000), but with pow(100, i) it has to actually call the function at runtime (because of the variable i being passed as argument), resulting with two results of pow in the form 0.99999999 and 99.999999 instead of 1 and 100 (or any 2 of the 3). When truncating to int after the multiply you "lose" two units.

This is another example of why converting to int from double is just pure evil: very hard to find subtle bugs in your program (not compiler bugs).

Btw, I am surprised that the compiler with O2 didn't unroll the loop, propagate the constants and reach the same optimization (replacing the function call with constant results).

Btw2 Scratch that, I am surprised that the compiler didn't just replace all you code with only two calls to printf.

like image 153
bolov Avatar answered Oct 02 '22 01:10

bolov