/* * Origin Niklaus * when trying to implement factorization of integers * * if we implement the pow function using unsigned long * long it passes but calling the cmath function fails * */ /* { dg-do run } */ /* { dg-options "-O2" } */ #include #include #include extern double pow(double,double); typedef unsigned long long ull; ull gcd (ull a, ull b) { if (b == 0) return a; return gcd (b, a % b); } int main () { ull numprod, denprod, gg; ull arr[] = { 2383, 31727, 132265613 }; ull acnt[] = { 1, 1, 1 }; int cnt = sizeof (arr) / sizeof (arr[0]), i; numprod = denprod = 1; /* * There was bug in optimizer when the actual output differs when we do * -O2 and -O0 * * if we replace num by numprod*=..... * and den by denprod*= a-1 * we get overflow and a different result * * whereas if you do it num/gcd(num,den) the overflow can be contained * */ for (i = 0; i < cnt; i++) { ull a = arr[i], b = acnt[i]; ull num = (ull) (pow ((double) a, (double)b + 1) - 1); ull den = a - 1; gg = gcd (num, den); num /= gg; den /= gg; numprod *= num; denprod *= den; gg = gcd (numprod, denprod); numprod /= gg; denprod /= gg; } if (numprod != 10004511787964928ULL) abort (); return 0; }