diff options
| author | Lars-Dominik Braun <lars@6xq.net> | 2019-02-11 11:49:19 +0100 | 
|---|---|---|
| committer | Lars-Dominik Braun <lars@6xq.net> | 2019-02-11 11:49:39 +0100 | 
| commit | 98cab31fc3659e33aef260efca55bf9f1753164c (patch) | |
| tree | f1affa84049ef9b268e6c4f521f000478b0f3a8e /system/base/unknown/src/mathlib | |
| parent | 71e2b36ccd05ea678e62e32ee6245df2b8d6ac17 (diff) | |
| download | eumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.tar.gz eumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.tar.bz2 eumel-src-98cab31fc3659e33aef260efca55bf9f1753164c.zip | |
Add source files from Michael
Diffstat (limited to 'system/base/unknown/src/mathlib')
| -rw-r--r-- | system/base/unknown/src/mathlib | 359 | 
1 files changed, 359 insertions, 0 deletions
| diff --git a/system/base/unknown/src/mathlib b/system/base/unknown/src/mathlib new file mode 100644 index 0000000..be44ff6 --- /dev/null +++ b/system/base/unknown/src/mathlib @@ -0,0 +1,359 @@ + 
 +PACKET mathlib DEFINES sqrt,**,exp,ln,log2,log10,sin,cos, 
 +                       tan,arctan,sind,cosd,tand,arctand,e,pi,
 +                       random,initializerandom :
 + 
 + 
 +REAL VAR rdg::0.4711; 
 + 
 +REAL PROC pi: 
 +   3.141592653589793. 
 +END PROC pi; 
 + 
 +REAL PROC e: 
 +  2.718281828459045. 
 +END PROC e; 
 + 
 +REAL PROC ln(REAL CONST x): 
 +LET ln2= 0.6931471805599453; 
 +log2(x)*ln2. 
 +END PROC ln; 
 + 
 +REAL PROC log2(REAL CONST z): 
 +INT VAR k::0,p::0; 
 +REAL VAR m::0.0,x::z,t::0.0,summe::0.0; 
 +IF   x>0.0 
 +THEN normal 
 +ELSE errorstop("log2 mit negativer zahl");4711.4711 
 +FI. 
 +normal: 
 + IF   x>=0.5 
 + THEN normalise downwards 
 + ELSE normalise upwards 
 +  FI; 
 +  IF   x>=0.1 AND x< 0.7071067811865475 THEN 
 +       t:=(x-0.5946035575013605)/(x+0.5946035575013605); 
 +       summe:=reihenentwicklung (t) - 0.75 
 +  FI; 
 +  IF  x>=0.7071067811865475 AND x < 1.0 THEN 
 +      t:=(x - 0.8408964152537145)/(x+0.8408964152537145); 
 +      summe:= reihenentwicklung(t)-0.25 
 +  FI; 
 +  summe-real(p - 4*k). 
 + 
 + normalise downwards: 
 +  WHILE  x>= 16.0 REP 
 +    x:=x/16.0;k:=k+1; 
 +  END REP; 
 +  WHILE  x>=0.5 REP 
 +    x:=x/2.0;p:=p-1; 
 +  END REP. 
 + 
 + normalise upwards: 
 +  WHILE x<=0.0625 REP 
 +    x:=x*16.0;k:=k-1; 
 +  END REP; 
 +  WHILE x<= 0.5 REP 
 +    x:=x*2.0;p:=p+1; 
 +  END REP. 
 + 
 +END PROC log2; 
 + 
 +REAL PROC reihenentwicklung(REAL CONST x):
 +  REAL VAR i::39.0,s::1.0/39.0; 
 +  LET ln2=0.6931471805599453; 
 +  WHILE i>1.0 REP 
 +    i:=i-2.0;s:=s*x*x + 1.0/i; 
 +  END REP; 
 +  s*2.0*x/ln2. 
 +END PROC reihenentwicklung; 
 + 
 +REAL PROC log10(REAL CONST x): 
 +  LET lg2=0.301029995664; 
 +  log2(x)*lg2. 
 +END PROC log10; 
 + 
 +REAL PROC sqrt(REAL CONST z): 
 +  REAL VAR y0,y1,x::z; 
 +  INT VAR p::0; 
 +  BOOL VAR q::FALSE; 
 +  IF   x<0.0 
 +  THEN errorstop("sqrt von negativer zahl");0.0
 +  ELSE correct 
 +  FI. 
 + 
 + correct: 
 +  IF   x=0.0 
 +  THEN 0.0 
 +  ELSE nontrivial 
 +  FI. 
 + 
 + nontrivial: 
 +  IF   x<0.01 
 +  THEN small 
 +  ELSE notsmall 
 +  FI. 
 + 
 + 
 + notsmall: 
 +  IF   x>1.0 
 +  THEN big 
 +  ELSE normal 
 +  FI. 
 + 
 + small: 
 +  WHILE x<0.01 REP 
 +    p:=p-1;x:=x*100.0; 
 +  END REP; 
 +  normal. 
 + 
 + big: 
 +  WHILE x>=1.0 REP
 +    p:=p+1;x:=x/100.0; 
 +  END REP; 
 +  normal. 
 + 
 + normal: 
 +  IF   x<0.1 
 +  THEN x:=x*10.0;q:=TRUE 
 +  FI; 
 +  y0:=10.0**p*(1.681595-1.288973/(0.8408065+x)); 
 +  IF   q 
 +  THEN y0:=y0/3.162278 
 +  FI; 
 +  y1:=(y0+z/y0)/2.0; 
 +  y0:=(y1+z/y1)/2.0; 
 +  y1:=(y0+z/y0)/2.0; 
 +  (y1-z/y1)/2.0+z/y1. 
 + 
 +END PROC sqrt; 
 + 
 +REAL PROC exp(REAL CONST z): 
 +  REAL VAR c,d,x::z, a, b ; 
 +  IF   x<-180.2187 
 +  THEN 0.0 
 +  ELIF x<0.0 
 +  THEN 1.0/exp(-x) 
 +  ELIF x=0.0 
 +  THEN 1.0 
 +  ELSE x:=x/0.6931471805599453;approx 
 +  FI. 
 + 
 + approx: 
 +  a:=floor(x/4.0)+1.0; 
 +  b:=floor(4.0*a-x); 
 +  c:=(4.0*a-b-x)*16.0; 
 +  d:=(c -floor(c))/16.0; 
 +  d:=d*0.6931471805599453; 
 +  ( (16.0 POWER a) / (2.0 POWER b) / (1.044273782427419 POWER c ))* 
 +  ((((((0.135910788320380e-2*d-0.8331563191293753e-2)*d 
 +  +0.4166661437490328e-1)*d-0.1666666658727157)*d+0.4999999999942539)*d 
 +  - 0.9999999999999844)*d+1.0). 
 + 
 +ENDPROC exp ; 
 + 
 +REAL OP POWER (REAL CONST basis, exponent) : 
 + 
 +  IF floor (exponent) = 0.0 
 +    THEN 1.0 
 +    ELSE power 
 +  FI . 
 + 
 +power : 
 +  REAL VAR counter := floor (abs (exponent)) - 1.0 , 
 +           result  := basis ; 
 +  WHILE counter > 0.0 REP 
 +    result := result * basis ; 
 +    counter := counter - 1.0 
 +  PER ; 
 +  IF exponent > 0.0 
 +    THEN result 
 +    ELSE 1.0 / result 
 +  FI . 
 + 
 +ENDOP POWER ; 
 + 
 +REAL PROC tan (REAL CONST x): 
 +  REAL VAR p; 
 +  p:=1.273239544735168*ABSx; 
 +  tg(p)*sign(x). 
 +END PROC tan; 
 + 
 +REAL PROC tand(REAL CONST x): 
 +  REAL VAR p; 
 +  p:=0.02222222222222222*ABSx; 
 +  tg(p)*sign(x). 
 +END PROC tand; 
 + 
 +REAL PROC tg(REAL CONST x): 
 +  REAL VAR r,s,u,q; 
 +  q:=floor(x);r:=x-q; 
 +  IF q = floor(q/2.0) * 2.0 
 +  THEN s:=r 
 +  ELSE s:=(1.0-r) 
 +  FI; 
 +  q:= q - floor(q/4.0) * 4.0 ; 
 +  u:=s*s; 
 +  s:=s*0.785398163397448; 
 +  s:=s/(((((((((-0.4018243865271481e-10*u-0.4404768172667185e-9)*u- 
 +  0.748183650813680e-8)*u-0.119216115119129e-6)*u-0.1909255769212821e-5)*u- 
 +0.3064200638849133e-4)*u-0.4967495424202482e-3)*u-0.8455650263333471e-2)*u- 
 +  0.2056167583560294)*u+1.0); 
 +  IF   q=0.0 
 +  THEN s 
 +  ELIF q=3.0 
 +  THEN -s 
 +  ELIF q=1.0 
 +  THEN 1.0/s 
 +  ELSE -1.0/s 
 +  FI . 
 + 
 +END PROC tg;
 + 
 +REAL PROC sin(REAL CONST x): 
 +  REAL VAR y,r; 
 +  INT VAR q; 
 +  y:=ABS x*1.273239544735168; 
 +  q:=int(y); 
 +  r:=y-real(q); 
 +  IF   x<0.0 
 +  THEN q:=q+4 
 +  FI; 
 +  sincos(q,r). 
 +END PROC sin; 
 + 
 +REAL PROC sind(REAL CONST x): 
 +  REAL VAR y,r; 
 +  INT VAR q; 
 +  y:=ABSx/45.0; 
 +  q:=int(y); 
 +  r:=y-real(q); 
 +  IF   x<0.0 
 +  THEN q:=q+4 
 +  FI; 
 +  sincos(q,r). 
 +END PROC sind; 
 + 
 + 
 +REAL PROC cos(REAL CONST x): 
 +  REAL VAR y,r; 
 +  INT VAR q; 
 +  y:=ABS x*1.273239544735168; 
 +  q:=int(y); 
 +  r:=y-real(q); 
 +  q:=q+2; 
 +  sincos(q,r). 
 +END PROC cos; 
 + 
 +REAL PROC cosd(REAL CONST x): 
 +  REAL VAR y,r; 
 +  INT VAR q; 
 +  y:=ABS x/45.0; 
 +  q:=int(y); 
 +  r:=y-real(q); 
 +  q:=q+2; 
 +  sincos(q,r). 
 +END PROC cosd; 
 + 
 + 
 +REAL PROC sincos(INT VAR q,REAL VAR r): 
 +  SELECT q MOD 8 + 1 OF 
 +  CASE 1 : sin approx(r) 
 +  CASE 2 : cos approx (1.0-r) 
 +  CASE 3 : cos approx(r) 
 +  CASE 4 : sin approx(1.0-r) 
 +  CASE 5 : - sin approx(r) 
 +  CASE 6 : - cos approx(1.0-r) 
 +  CASE 7 : - cos approx(r) 
 +  CASE 8 : - sin approx(1.0-r) 
 +  OTHERWISE 0.0 
 +  END SELECT 
 +END PROC sincos; 
 + 
 +REAL PROC sin approx(REAL CONST x): 
 +  REAL VAR z::x*x; 
 +  x*((((((0.6877101540593035e-11*z-0.1757149296873372e-8)*z+0.313361621667256
 +8
 +e-6)*z-0.3657620415845891e-4)*z+0.2490394570188737e-2)*z-0.807455121882e-1 
 +)*z+0.7853981633974483). 
 +END PROC sin approx; 
 + 
 +REAL PROC cos approx(REAL CONST x): 
 +  REAL VAR z::x*x; 
 +  (((((( -0.3857761864560276e-12*z+0.115004970178141e-9)*z-0.246113638267419e
 +-7)*z+0.3590860445885748e-5)*z-0.3259918869266875e-3)*z+0.1585434424381541e-1
 +)*z-0.3084251375340425)*z+1.0. 
 +END PROC cos approx; 
 + 
 +REAL PROC arctan(REAL CONST x): 
 +REAL VAR z::x*x; 
 +IF   x<0.0 THEN -arctan(-x) 
 +ELIF x>1.0 THEN 3.141592653589792/2.0-arctan(1.0/x) 
 +ELIF x*1.0e16>2.67949192431e15   THEN pi/6.0+arctan(1.732050807568877-4.0 
 +/(x+1.732050807568877)) 
 +ELSE  x/(((((((0.0107090276046822*z-0.01647757182108040)*z 
 +      +0.02177846332482151)*z-0.03019339673273880)*z+0.04656083561183398)*z 
 +      -0.0888888888888888)*z+0.3333333333333333)*z+1.0)FI. 
 +END PROC arctan; 
 + 
 +REAL PROC arctand(REAL CONST x): 
 +  arctan(x)/3.1415926589793*180.0. 
 +END PROC arctand; 
 + 
 + 
 +BOOL PROC even(INT CONST number): 
 + (number DIV 2)*2=number. 
 +END PROC even; 
 + 
 +REAL OP **(REAL CONST base,exponent): 
 +  IF   base<0.0 
 +  THEN errorstop("hoch mit negativer basis") 
 +  FI; 
 +  IF   base=0.0 
 +  THEN test exponent 
 +  ELSE
 +      exp(exponent*ln(base)) 
 +  FI. 
 + 
 + test exponent: 
 +  IF   exponent=0.0 
 +  THEN errorstop("0**0 geht nicht");4711.4711 
 +  ELSE 0.0 
 +  FI. 
 + 
 +END OP **; 
 + 
 + 
 +REAL PROC sign(REAL CONST number): 
 +  IF   number >0.0  THEN 1.0 
 +  ELIF number <0.0  THEN -1.0 
 +  ELSE 0.0 
 +  FI. 
 +END PROC sign ;
 + 
 +REAL OP **(REAL CONST a,INT CONST b): 
 +REAL VAR p::1.0,r::a;INT VAR n::ABS b; 
 +WHILE n>0 REP 
 +  IF   n MOD 2=0 
 +  THEN n:=n DIV 2;r:=r*r 
 +  ELSE n DECR 1;p:=p*r 
 +  FI; 
 +END REP; 
 +IF   b>0 
 +THEN p 
 +ELSE 1.0/p 
 +FI. 
 +END OP **; 
 + 
 + 
 + 
 +REAL PROC random: 
 +rdg:=rdg+pi;rdg:=rdg*rdg;rdg:=rdg*rdg;rdg:=rdg*rdg;rdg:=frac(rdg);rdg. 
 +END PROC random; 
 + 
 + 
 +PROC initializerandom(REAL CONST z): 
 + rdg:=z; 
 +END PROC initializerandom; 
 + 
 +END PACKET mathlib; 
 | 
