
package body IPowers is

  procedure IPower(I: in Integer; S1: in Scalar; S2,Tmp: in out Scalar) is
    J: Integer := abs(I);
    S: Scalar renames Tmp;
  begin
    if J>1 then
      if I=2 then Prod(S1,S1,S2); return; end if;
      if I>0 then
        Copy(S1,S);
      else
        Inv(S1,S);
        if J=2 then Prod(S,S,S2); return; end if;
      end if;
      if (J rem 2)=0 then
        Assign(1,S2);
      else
        Copy(S,S2);
      end if;
      J := J/2;
      while J>0 loop
        Sqr(S);
        if (J rem 2) /= 0 then
          Mult(S,S2);
        end if;
        J := J/2;
      end loop;
    elsif I=0 then
      Assign(1,S2);
    elsif I=1 then
      Copy(S1,S2);
    else           --- I = -1
      Inv(S1,S2);
    end if;
  end IPower;

  procedure IPower(I: in Integer; S1: in Scalar; S2: in out Scalar) is
    J: Integer := abs(I);
  begin
    if J>1 then
      if I=2 then Prod(S1,S1,S2); return; end if;
      declare
        S: Scalar;
      begin
        if I>0 then
          Copy(S1,S);
        else
          Inv(S1,S);
          if J=2 then Prod(S,S,S2); return; end if;
        end if;
        if (J rem 2)=0 then
          Assign(1,S2);
        else
          Copy(S,S2);
        end if;
        J := J/2;
        while J>0 loop
          Sqr(S);
          if (J rem 2) /= 0 then
            Mult(S,S2);
          end if;
          J := J/2;
        end loop;
      end;
    elsif I=0 then
      Assign(1,S2);
    elsif I=1 then
      Copy(S1,S2);
    else           --- I = -1
      Inv(S1,S2);
    end if;
  end IPower;

end IPowers;
