
package body MPFR.Floats.EFuns is


  procedure Root(K: in Positive; X,DX: in MPFloat; YL,YU: in out MPFloat) is
    Rounded: Int;
    A: MPFR_T renames YU.Val;
  begin
    Reformat(YL.Val);
    Reformat(YU.Val);
    MPFR_Abs(Rounded,A,DX.Val,GMP_RNDU);
    MPFR_Sub(Rounded,YL.Val,X.Val,A,GMP_RNDD);
    MPFR_Root(Rounded,YL.Val,YL.Val,Unsigned_Long(K),GMP_RNDD);
    MPFR_Add(Rounded,YU.Val,X.Val,A,GMP_RNDU);
    MPFR_Root(Rounded,YU.Val,YU.Val,Unsigned_Long(K),GMP_RNDU);
    if Problem then Report("EFuns.Root"); end if;
  end Root;

  procedure ExpUp(X: in MPFloat; Y: in out MPFloat) is
    Rounded: Int;
  begin
    Reformat(Y.Val);
    MPFR_Exp(Rounded,Y.Val,X.Val,GMP_RNDU);
    if Problem then Report("EFuns.ExpUp"); end if;
  end ExpUp;

  procedure ExpDown(X: in MPFloat; Y: in out MPFloat) is
    Rounded: Int;
  begin
    Reformat(Y.Val);
    MPFR_Exp(Rounded,Y.Val,X.Val,GMP_RNDD);
    if Problem then Report("EFuns.ExpDown"); end if;
  end ExpDown;

  procedure Exp(X,DX: in MPFloat; YL,YU: in out MPFloat) is
    Rounded: Int;
    A: MPFR_T renames YU.Val;
  begin
    Reformat(YL.Val);
    Reformat(YU.Val);
    MPFR_Abs(Rounded,A,DX.Val,GMP_RNDU);
    MPFR_Sub(Rounded,YL.Val,X.Val,A,GMP_RNDD);
    MPFR_Exp(Rounded,YL.Val,YL.Val,GMP_RNDD);
    MPFR_Add(Rounded,YU.Val,X.Val,A,GMP_RNDU);
    MPFR_Exp(Rounded,YU.Val,YU.Val,GMP_RNDU);
    if Problem then Report("EFuns.Exp"); end if;
  end Exp;

  procedure Log(X,DX: in MPFloat; YL,YU: in out MPFloat) is
    Rounded: Int;
    A: MPFR_T renames YU.Val;
  begin
    Reformat(YL.Val);
    Reformat(YU.Val);
    MPFR_Abs(Rounded,A,DX.Val,GMP_RNDU);
    MPFR_Sub(Rounded,YL.Val,X.Val,A,GMP_RNDD);
    MPFR_Log(Rounded,YL.Val,YL.Val,GMP_RNDD);
    MPFR_Add(Rounded,YU.Val,X.Val,A,GMP_RNDU);
    MPFR_Log(Rounded,YU.Val,YU.Val,GMP_RNDU);
    if Problem then Report("EFuns.Log"); end if;
  end Log;

  procedure ArcCos(X,DX: in MPFloat; YL,YU: in out MPFloat) is
    Rounded: Int;
    A: MPFR_T renames YU.Val;
  begin
    Reformat(YL.Val);
    Reformat(YU.Val);
    MPFR_Abs(Rounded,A,DX.Val,GMP_RNDU);
    MPFR_Add(Rounded,YL.Val,X.Val,A,GMP_RNDU);
    MPFR_ACos(Rounded,YL.Val,YL.Val,GMP_RNDD);
    MPFR_Sub(Rounded,YU.Val,X.Val,A,GMP_RNDD);
    MPFR_ACos(Rounded,YU.Val,YU.Val,GMP_RNDU);
    if Problem then Report("EFuns.ArcCos"); end if;
  end ArcCos;

  procedure ArcSin(X,DX: in MPFloat; YL,YU: in out MPFloat) is
    Rounded: Int;
    A: MPFR_T renames YU.Val;
  begin
    Reformat(YL.Val);
    Reformat(YU.Val);
    MPFR_Abs(Rounded,A,DX.Val,GMP_RNDU);
    MPFR_Sub(Rounded,YL.Val,X.Val,A,GMP_RNDD);
    MPFR_ASin(Rounded,YL.Val,YL.Val,GMP_RNDD);
    MPFR_Add(Rounded,YU.Val,X.Val,A,GMP_RNDU);
    MPFR_ASin(Rounded,YU.Val,YU.Val,GMP_RNDU);
    if Problem then Report("EFuns.ArcSin"); end if;
  end ArcSin;

  procedure Cos(X: in MPFloat; YL,YU: in out MPFloat) is
    Rounded: Int;
  begin
    Reformat(YL.Val);
    Reformat(YU.Val);
    MPFR_Cos(Rounded,YL.Val,X.Val,GMP_RNDD);
    MPFR_Cos(Rounded,YU.Val,X.Val,GMP_RNDU);
    if Problem then Report("EFuns.Cos"); end if;
  end Cos;

  procedure Sin(X: in MPFloat; YL,YU: in out MPFloat) is
    Rounded: Int;
  begin
    Reformat(YL.Val);
    Reformat(YU.Val);
    MPFR_Sin(Rounded,YL.Val,X.Val,GMP_RNDD);
    MPFR_Sin(Rounded,YU.Val,X.Val,GMP_RNDU);
    if Problem then Report("EFuns.Sin"); end if;
  end Sin;

end MPFR.Floats.EFuns;
