import java.util.Scanner;

class PGPuissance {

/**
  Puissance naive terminale
  @param[in] x - un réel
  @param[in] n - un entier
  @param[in] y - le cumul
  @return Puissance x^n
*/

public static double puiss1Rec(double x, int n, double y)
{
  return (n == 0 ? y : puiss1Rec(x,n - 1,x * y));
}

/**
  Puissance naive (suppose n >= 0)
  @param[in] x - un réel
  @param[in] n - un entier
  @return Puissance x^n
*/

public static double puiss1(double x, int n)
{
  return puiss1Rec(x,n,1.0);
}

/**
  Carré d'un réel
  @param[in] x - un réel
  @return carré de x
*/

public static double carre(double x)
{
  return (x * x);
}

/**
  Puissance basée sur la parité de n (suppose n >= 0)
  @param[in] x - un réel
  @param[in] n - un entier
  @return Puissance x^n
*/

public static double puiss2(double x, int n)
{
  if (n == 0)
  {
    return 1.0;
  }
  else if (n % 2 == 0)
  {
    return carre(puiss2(x,n / 2));
  }
  else
  {
    return x * carre(puiss2(x,(n - 1) / 2));
  }
}

/**
  Puissance terminale
  @param[in] x - un réel
  @param[in] n - un entier
  @param[in] y - le cumul
  @return Puissance x^n
*/

public static double puiss3Rec(double x, int n, double y)
{
  if (n == 0)
  {
    return y;
  }
  else if (n % 2 == 0)
  {
    return puiss3Rec(x * x,n / 2,y);
  }
  else
  {
    return puiss3Rec(x,n - 1,x * y);
  }
}

/**
  Puissance basée sur la parité de n (suppose n >= 0)
  @param[in] x - un réel
  @param[in] n - un entier
  @return Puissance x^n
*/

public static double puiss3(double x, int n)
{
  return puiss3Rec(x,n,1.0);
}

/**
  Puissance itérative basée sur la parité de n (suppose n >= 0)
  @param[in] x - un réel
  @param[in] n - un entier
  @return Puissance x^n
*/

public static double puiss4(double x, int n)
{
  double y = 1.0;
  while (n != 0)
  {
    if (n % 2 == 0)
    {
      x *= x;
      n /= 2;
    }
    else
    {
      y *= x;
      n -= 1;
    }
  }
  return y;
}

public static void main(String[] args)
{
  Scanner input = new Scanner(System.in);
  double x;
  System.out.print("Puissance x? ");
  x = input.nextDouble();
  int n;
  System.out.print("Ordre n? ");
  n = input.nextInt();
  System.out.println("==> puiss1(x,n) vaut " + puiss1(x,n));
  System.out.println("==> puiss2(x,n) vaut " + puiss2(x,n));
  System.out.println("==> puiss3(x,n) vaut " + puiss3(x,n));
  System.out.println("==> puiss4(x,n) vaut " + puiss4(x,n));
}

}
