unit mathlib;
{$IFDEF FPC}
  {$MODE DELPHI}{$H+}
{$ENDIF}
{$INLINE ON}
(***************************************)
(* Copyright (C) 2014, SHIRAISHI Kazuo *)
(***************************************)

interface
uses
  Classes, SysUtils,math;

function REMAINDER( x,y:double):double;overload;
function SQRT( x:double):double;  overload;
function TAN( x:double):double;   overload;
function COT( x:double):double;   overload;
function SEC( x:double):double;   overload;
function CSC( x:double):double;   overload;
function ACOS( x:double):double;  overload;
function ASIN( x:double):double;  overload;
function TANDEG( x:double):double; overload;
function COTDEG( x:double):double; overload;
function SECDEG( x:double):double; overload;
function CSCDEG( x:double):double; overload;
function ACOSDEG( x:double):double;inline;overload;
function ASINDEG( x:double):double;inline;overload;
function ANGLE( x,y:double):double; overload;
function ANGLEDEG( x,y:double):double;inline;overload;
function COSH( x:double):double;    overload;
function SINH( x:double):double;    overload;
function EXP( x:double):double;     overload;
function LOG( x:double):double;     overload;
function LOG2( x:double):double;    overload;
function LOG10( x:double):double;   overload;
function Power( x,y:double):double; overload;

const
    DefaultExcode=$03EA0BB9;   // Ematherror 1002 EZeroDivide 3001

implementation
uses
     base,base2,math2sub,baslib;


function REMAINDER(x,y:double):double;
begin
   excode:=$03EB0BBE;   // 1003 3006
   result:=x-y*system.int(x/y);
   excode:=DefaultExcode
end;

function SQRT( x:double):double;
begin
 if x<0 then setexception(3005);        //faster
 //excode:=$03EB0BBD;   // 1003    3005
 result:=system.SQRT(x);
 //excode:=DefaultExcode;
end;

function TAN( x:double):double;
begin
    excode:=$03EB03EB;   // 1003  1003
    result:=math.tan(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode
end;

function COT( x:double):double;
begin
    excode:=$03EB03EB;   // 1003  1003
    result:=math.cot(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode
end;

function SEC( x:double):double;
begin
    excode:=$03EB03EB;   // 1003  1003
    result:=math.sec(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode
end;

function CSC( x:double):double;
begin
    excode:=$03EB03EB;   // 1003  1003
    result:=math.csc(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode
end;
function ACOS( x:double):double;
 begin
      excode:=$03EB0BBF;   // 1003 3007
      result:=math2sub.acos(x);
      excode:=DefaultExcode
 end;

 function ASIN( x:double):double;
 begin
      excode:=$03EB0BBF;   // 1003 3007
      result:=math2sub.asin(x);
      excode:=DefaultExcode
 end;

function TANDEG( x:double):double;
var
  y:extended;
begin
    excode:=$03EB03EB;   // 1003  1003
    y:=math2sub.cosdeg(x);
    if y=0 then
       setexception(1003)
    else
       begin
         result:=math2sub.sindeg(x)/y;
         {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
       end;
    excode:=DefaultExcode
end;

function COTDEG( x:double):double;
var
  y:extended;
begin
    excode:=$03EB03EB;   // 1003  1003
    y:=math2sub.sindeg(x);
    if y=0 then
       setexception(1003)
    else
       begin
         result:=math2sub.cosdeg(x)/y;
         {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
       end;
    excode:=DefaultExcode
end;

 function SECDEG( x:double):double;
begin
    excode:=$03EB03EB;   // 1003  1003
    result:=math2sub.secdeg(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode
end;

function CSCDEG( x:double):double;
begin
    excode:=$03EB03EB;   // 1003  1003
    result:=math2sub.cscdeg(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode
end;


function ACOSDEG( x:double):double;inline;
begin
    result:= acos(x)*degree
end;

function ASINDEG( x:double):double;inline;
begin
    result:= asin(x)*degree
end;

function ANGLE( x,y:double):double;
begin
   if (x=0) and (y=0) then
      setexception(3008)
   else
      result:=ArcTan2(y,x)
end;

function ANGLEdeg( x,y:double):double;inline;
begin
   result:=ANGLE(x,y)*degree
end;

function COSH( x:double):double;
begin
    excode:=$03EB0000;   // 1003     0
    result:=math2sub.cosh(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode
end;

function SINH( x:double):double;
begin
    excode:=$03EB0000;   // 1003     0
    result:=math2sub.sinh(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode
end;



function EXP( x:double):double;
begin
    excode:=$03EB03EB;   // 1003    1003
    result:=system.exp(x);
    {$IFDEF FPUX87} asm fwait end ; {$ENDIF}
    excode:=DefaultExcode;
 end;

function LOG( x:double):double;
begin
    if x<=0 then setexception(3004);
    result:=ln(x);
end;

function LOG2( x:double):double;
begin
    if x<=0 then setexception(3004);
    result:=Math.log2(x);
end;

function LOG10( x:double):double;
begin
    if x<=0 then setexception(3004);
    result:=Math.log10(x);
end;




function Power( x,y:double):double;
begin
   if x>0 then
      begin
      {$IFNDEF Windows}
      excode:=$03EA03EA;   // 1002    1002
      {$ENDIF}
      result:=math.power(x,y);
      {$IFNDEF Windows}
      excode:=DefaultExcode;
      {$ENDIF}
      end
   else if x=0 then
     if y=0 then
        result:=1
     else if y<0 then
        setexception(3003)
     else
        result:=0
   else { x<0 }
      if system.int(y)=y then
         result:=math.power(x,y)
      else
         setexception(3002)
end;


end.

