/* 
 * Origin Niklaus <niklaus@gmail.com>
 * 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<stdio.h>
#include<math.h>
#include<stdlib.h>
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;
}
