|
|
DataMuseum.dkPresents historical artifacts from the history of: RC3500 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC3500 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 16896 (0x4200)
Types: TextFileVerbose
Names: »tsqrttest«
└─⟦2c55ea56f⟧ Bits:30001844 SW-save af projekt 1000, Alarm-system
└─⟦6b41451d2⟧
└─⟦this⟧ »tsqrttest«
job bbl 3 600 time 11 0 perm mini 100 1 size 92000
(
pascal80 codesize.12000 spacing.12000 debugenvir
bsqrttest = set 1 mini
bsqrttest = move pass6code
if ok.yes
scope user bsqrttest
finis)
(* process "sqrttest", 25/8/80, pemn.
this program tests the modules: realtype, linttype and zontype.
*)
process sqrttest( var sysvector : system_vector );
(*
module : zonetype.
pemn, 22/8/80.
adopted from a module ( testopen testout ) by wib and stb.
*)
type
buffertype = record
first, last, next : integer;
name : alfa;
data : array ( 1 .. 80 ) of char
end;
zone = record
testoutpool : pool 1 of buffertype;
testoutsem : semaphore;
opsem : ^ semaphore;
opref : reference
end;
procedure outopen (
var z: zone;
modulename: alfa;
ps: ^semaphore);
var
opref: reference;
\f
begin
z.opsem:= ps;
while openpool(z.testoutpool) do
begin
alloc (opref, z.testoutpool, z.testoutsem);
opref^.u1:= 2;
lock opref as opbuf: buffertype do
with opbuf do
begin
first:= 6+alfalength;
next:= 1;
name:= modulename;
end (* with opbuf do *);
return(opref);
end; (* while openpool *)
end (* testopen *);
\f
procedure outchar( var z : zone; ch : char );
(* writes the ch into the output buffer . *)
begin
if nil( z. opref ) then
begin
wait( z.opref, z. testoutsem );
lock z.opref as opbuf : buffertype do
with opbuf do
begin
data( 1 ) := ch;
next := 2
end
end
else
lock z.opref as opbuf : buffertype do
with opbuf do
begin
data( next ) := ch;
next:= next + 1;
end;
end (* outchar *);
\f
procedure outinteger(var z:zone;int,positions:integer);
(* writes the integer "int" into opbuf starting at
"outputpoint", which is updated accordingly *)
const
maxpos = 20; (* max number of positions in layout *)
base = 10;
var
digits:array(1..maxpos) of char;
used,i:integer;
negative:boolean;
begin
(* first we initialise the digits array *)
for i:=1 to maxpos do digits(i):=sp;
i:=maxpos;
negative:= int<0;
int:=abs(int);
repeat
(* now we unpack the digits backwards and put them
into the digits array *)
digits(i):= chr(int mod base + ord("0"));
int:=int div base;
i:=i-1;
until (i=1) or (int=0);
if negative then
begin
digits(i):="-";
i:=i-1;
end;
used:=maxpos-i;
if int <> 0 then digits(1):= "*";
(* i n{ste linje skal 20 erstattes af maxpos !!!!!!!!!!!!!!!!!!!!!!!*)
if (not (positions in (. 1 .. 20 .)) )
or (positions < used) then
positions:=used;
for i:=maxpos+1-positions to maxpos do
outchar( z, digits(i) );
end (* out integer *);
\f
procedure outstring( var z:zone; text: alfa);
(* writes the text into opbuf starting at opbuf.next
which is updated accordingly *)
var
i: integer;
begin
for i:=1 to alfalength do
outchar( z, text(i) );
end (* out string *);
\f
procedure outnl( var z : zone );
begin
outchar( z, nl );
with z do begin
lock opref as opbuf : buffertype do
with opbuf do
last := next + 16;
opref^ .u2 := 0;
signal( opref, opsem^ )
end
end;
procedure outclose( var z : zone );
begin
with z do
begin
if not nil( opref ) then outnl( z );
wait( opref, testoutsem );
release( opref )
end
end;
var
z : zone;
i : integer;
procedure error( kind, where : integer );
forward;
(*
module: lint_type
22/8/80, pemn.
*)
const
int___n = 32767;
(* the range of values of the standard type "integer"
must contain the closed interval: [ -int___n .. int___n ]
*)
lint___base = 181;
(* the value of "lint___base" is the base of the ( multi-length )
integer of the type "lint". the value must satisfy:
lint___base <= sqrt( int___n + 1 )
*)
lint___digits = 30;
(* the value of "lint___digits" is the number of digits ( base:
"lint___base" ) in the ( multi-length ) integers of the type "lint" .
*)
type
lint = array ( 1 .. lint___digits ) of integer;
(* the value l of the type "lint" is defined to be:
l[1] + l[2]*( lint___base**1 ) + l[3]*( lint___base**2 ) + ......
......+ l[k]*( lint___base**(k-1) ) + ...............
ending with k=lint___digits.
The vlues of the digits l[i] must satisfy:
-lint___base <= l[ lint___digits ] < lint___base
and 0 <= l[k] < lint___base , for k= 1,2....(lint___digits - 1 ) .
reference: Chr. Gram et al : Datamatik, vol 2, Regnecentralen/Studentlitteratur.
*)
function lint_lt_zero( li : lint ) : boolean;
forward;
function lint_eq( la, lb : lint ) : boolean;
forward;
function lint_neg( li : lint ) : lint;
forward;
function lint_eq_zero( li : lint ) : boolean;
forward;
procedure lint___exception( kind, where : integer );
begin
(* this procedure is called by routines in this prefix
when the specified function cannot be performed. It may
also be called similar procedures on a higher level of
abstraction.
*)
error( kind, where )
end;
function lint_from_integer( i : integer ) : lint;
var
a : lint;
k : integer;
begin
if i < 0 then
a := lint_neg( lint_from_integer( -i ) )
else
for k := 1 to lint___digits do
begin
a(k) := i mod lint___base;
i := i div lint___base
end;
lint_from_integer := a
end;
function lint_neg( li : lint ) : lint;
var
digit, carry : integer;
r : lint;
k : integer;
begin
carry := 0;
for k := 1 to ( lint___digits - 1 ) do
begin
digit := lint___base - carry -li(k);
if digit = lint___base then digit := 0
else
carry := 1;
r(k) := digit
end;
digit := -li( lint___digits ) - carry;
if digit = lint___base then
lint___exception( 1, 1 )
else
r( lint___digits ) := digit;
lint_neg := r
end;
function lint_abs( li : lint ) : lint;
begin
if lint_lt_zero( li ) then
lint_abs := lint_neg( li )
else
lint_abs := li
end;
function lint_add( la, lb : lint ) : lint;
var
k : integer;
r : lint;
digit, carry : integer;
begin
carry := 0;
for k := 1 to lint___digits do
begin
digit := la(k) + lb(k) + carry;
if digit >= lint___base then
begin
carry := 1;
digit := digit - lint___base
end
else
carry := 0;
r(k) := digit
end;
if ( carry = 1 ) or ( r( lint___digits ) < ( - lint___base ) ) then
lint___exception( 1, 2 );
lint_add := r
end;
function lint_sub( la, lb : lint ) : lint;
begin
lint_sub := lint_add( la, lint_neg( lb ) )
end;
function lint_mult( la, lb : lint ) : lint;
var
sign : boolean;
r : lint;
kk, k, i, j : integer;
c, prod, mente, ciffer : integer;
begin
sign := false;
if lint_lt_zero( la ) then
begin
sign := not sign; la := lint_neg( la )
end;
if lint_lt_zero( lb ) then
begin
sign := not sign; lb := lint_neg( lb )
end;
for k := 1 to lint___digits do r( k ) := 0;
for k := 1 to lint___digits do
for i := 1 to k do
begin
prod := la( i ) * lb( k - i + 1 );
mente := prod div lint___base;
ciffer := prod - mente * lint___base;
kk := k;
repeat
begin
if kk > lint___digits then lint___exception( 1, 3 );
c := r( kk ) + ciffer; r( kk ) := c;
if c >= lint___base then
begin
mente := mente + 1;
r( kk ) := c - lint___base
end;
ciffer := mente;
mente := 0;
kk := kk + 1
end
until ciffer = 0
end (* i , k ...... *);
for i := 2 to lint___digits do
begin
c := la( i );
for j := lint___digits - i + 2 to lint___digits do
if c * lb( j ) <> 0 then lint___exception( 1, 4 )
end (* i .... *);
if sign then
lint_mult := lint_neg( r )
else
lint_mult := r
end;
procedure lint___quotient( la, lb : lint; var lq : lint; var lr : lint );
var
k, d, i, j : integer;
c1, qk, forrige_qk, ai, mente_j : integer;
rest_for_stor, equal : boolean;
begin
if lint_lt_zero( lb ) then lint___exception( 2, 5 );
if lint_eq_zero( lb ) then lint___exception( 2, 6 );
for k := 1 to lint___digits do lq( k ) := 0;
d := lint___digits;
while lb( d ) = 0 do d := d - 1;
c1 := lb( d );
for k := lint___digits - d + 1 downto 1 do
begin
i := k + d - 1;
forrige_qk := 0;
repeat
ai := la( i );
if ai >= 0 then
qk := ai div c1
else
qk := ( ai - c1 + 1 ) div c1;
if qk = - forrige_qk then
begin
if qk < 0 then
qk := qk + 1
else
qk := qk - 1
end;
forrige_qk := qk;
mente_j := la( k ) - lb( 1 ) * qk; la( k ) := mente_j;
for j := 2 to d do
begin
if mente_j >= 0 then
mente_j := mente_j div lint___base
else
mente_j := ( mente_j - lint___base + 1 ) div lint___base;
la( k + j - 2 ) := la( k + j - 2 ) - mente_j * lint___base;
mente_j := la( k + j - 1 ) + mente_j - lb( j ) * qk;
la( k + j - 1 ) := mente_j
end;
lq( k ) := lq( k ) + qk;
if mente_j >= 0 then
begin
j := d; equal := true; rest_for_stor := true;
repeat
if la( k + j - 1 ) <> lb( j ) then
begin
equal := false;
if la( k + j - 1 ) < lb( j ) then rest_for_stor := false
end;
j := j - 1
until
( not equal ) or ( j = 0 )
end
until
( not rest_for_stor ) and ( mente_j >= 0 );
if k > 1 then
begin
la( i - 1 ) := la( i - 1 ) + la( i ) * lint___base;
la( i ) := 0
end
end (* for k:= ...... *);
lr := la
end;
function lint_div( la, lb : lint ) : lint;
var
lq, lr : lint;
begin
lint___quotient( la, lb, lq, lr );
lint_div := lq
end;
function lint_mod( la, lb : lint ) : lint;
var
lq, lr : lint;
begin
lint___quotient( la, lb, lq, lr );
lint_mod := lr
end;
function lint_lt_zero( li : lint ) : boolean;
begin
lint_lt_zero := li( lint___digits ) < 0
end;
function lint_lt( la, lb : lint ) : boolean;
var
eq, lt : boolean;
k : integer;
begin
eq := true; lt := false;
k := lint___digits;
while ( k >= 1 ) and eq do
begin
if la( k ) <> lb( k ) then
begin
eq := false;
lt := la( k ) < lb( k )
end;
k := k - 1
end;
lint_lt := lt
end;
function lint_eq_int( li : lint; i : integer ) : boolean;
begin
lint_eq_int := lint_eq( li, lint_from_integer( i ) )
end;
function lint_eq_zero( li : lint ) : boolean;
var
eq : boolean;
k : integer;
begin
eq := true; k := 1;
while ( k <= lint___digits ) and eq do
begin
if li( k ) <> 0 then eq := false;
k := k + 1
end;
lint_eq_zero := eq
end;
function lint_eq( la, lb : lint ) : boolean;
var
eq : boolean;
k : integer;
begin
eq := true; k := 1;
while ( k <= lint___digits ) and eq do
begin
if la( k ) <> lb( k ) then eq := false;
k := k + 1
end;
lint_eq := eq
end;
procedure lint_output( var z : zone; zeroes : boolean; li : lint; positions : integer );
const
g1 = 10;
max_digits = 50;
var
a1 : array ( 1 .. max_digits ) of integer;
i, j, ciffer, mente, d, bl : integer;
sign : boolean;
begin
if lint_lt_zero( li ) then
begin
sign := true;
li := lint_neg( li )
end
else
sign := false;
(* convert "li" to base 10 in "a1" : *)
for j := 1 to max_digits do a1( j ) := 0;
for i := lint___digits downto 1 do
begin
mente := li( i );
for j := 1 to max_digits do
begin
ciffer := a1( j ) * lint___base + mente;
mente := ciffer div g1;
a1( j ) := ciffer - mente * g1
end;
if mente > 0 then lint___exception( 3, 7 )
end;
d := 1;
for i := 2 to max_digits do
if a1( i ) <> 0 then d := i;
bl := positions - d;
if sign then bl := bl - 1;
if zeroes then
begin
if sign then outchar( z, '-' );
for i := 1 to bl do outchar( z, '0' )
end
else
begin
for i := 1 to bl do outchar( z, ' ' );
if sign then outchar( z, '-' )
end;
for i := d downto 1 do
outchar( z, chr( a1( i ) + ord( '0' ) ) )
end;
(*
module: real_type.
pemn, 21/8/80.
a value r of type "real" is represented as a fraction c/d, where c and
d are ( multilength ) integer values of type "lint" satisfying:
d <> 0 and c and d are relative prime.
reference: D.Knuth: Semi numarical algorithms, sec. 4.5.1 .
*)
type
real = record
c, d : lint
end;
procedure real_output( var z : zone; r : real; positions, decimals : integer );
forward;
procedure real___exception( kind, where : integer );
(* kind =
1 , the function is not implemented.
2 , divisor is zero.
*)
begin
(* this procedure is called by routines in this prefix
when the specified function cannot be performed. *)
lint___exception( 0, kind * 100 + where )
end;
function real_from_integer( i : integer ) : real;
var
r : real;
begin
with r do
begin
c := lint_from_integer( i );
d := lint_from_integer( 1 )
end;
real_from_integer := r
end;
function real_const( char_rep : alfa ) : real;
begin
real___exception( 1, 1 );
real_const := real_from_integer( 0 )
end;
function real_to_integer( r : real ) : integer;
begin
real___exception( 1, 2 );
real_to_integer := 0
end;
function real___normalize( r : real ) : real;
var
u, v, w : lint;
r1 : real;
begin
u := lint_abs( r.c );
v := lint_abs( r.d );
while not lint_eq_zero( v ) do
begin
w := lint_mod( u, v );
u := v;
v:= w
end;
if lint_eq_int( u, 1 ) then
real___normalize := r
else
begin
r1.c := lint_div( r.c, u );
r1.d := lint_div( r.d, u );
real___normalize := r1
end
end;
function real_neg( r : real ) : real;
var
r1 : real;
begin
with r1 do
begin
c := lint_neg( r.c );
d := r.d
end;
real_neg := r1
end;
function real_abs( r : real ) : real;
var
r1 : real;
begin
with r1 do
begin
c := lint_abs( r.c );
d := lint_abs( r.d )
end;
real_abs := r1
end;
function real_add( r1, r2 : real ) : real;
var
r : real;
begin
with r do
begin
c := lint_add( lint_mult( r1.c, r2.d ), lint_mult( r2.c, r1.d ) );
d := lint_mult( r1.d, r2.d )
end;
real_add := real___normalize( r )
end;
function real_sub( r1, r2 : real ) : real;
var
r : real;
l1,l2 : lint;
begin
with r do
begin
l1:= lint_mult( r1.c, r2.d );
lint_output( z, false, l1, 20 ); outnl( z );
l2:= lint_mult( r2.c, r1.d );
lint_output( z, false, l2, 20 ); outnl( z );
c:= lint_sub( l1, l2 );
d := lint_mult( r1.d, r2.d );
lint_output( z, false, c, 20 ); outnl( z );
lint_output( z, false, d, 20 ); outnl( z );
end;
real_sub := real___normalize( r )
end;
function real_mult( r1, r2 : real ) : real;
var
r : real;
begin
with r do
begin
c := lint_mult( r1.c, r2.c );
d := lint_mult( r1.d, r2.d )
end;
real_mult := real___normalize( r )
end;
function real_div( r1, r2 : real ) : real;
var
r : real;
begin
if lint_eq_zero( r2.c ) then real___exception( 2, 3 );
with r do
begin
c := lint_mult( r1.c, r2.d );
d := lint_mult( r2.c, r1.d )
end;
real_div := real___normalize( r )
end;
function real_lt( r1, r2 : real ) : boolean;
var
l1,l2 : lint;
s1, s2 : boolean;
begin
s1 := lint_lt_zero( r1.d );
s2 := lint_lt_zero( r2.d );
l1 := lint_mult( r1.c, r2.d );
l2 := lint_mult( r1.d, r2.c );
if s1 = s2 then
real_lt := lint_lt( l1, l2 )
else
real_lt := lint_lt( l2, l1 )
end;
function real_sqrt( var z : zone; x : real; eps : real ) : real;
var
x0, x1 : real;
y0, y1 : real;
b : boolean;
begin
(* newton's method.
x must satisfy: x > 1 .
*)
x1 := x;
repeat
x0 := x1;
x1 := real_div( real_add( x0, real_div ( x, x0 ) ), real_from_integer( 2 ) );
real_output( z, x1, 10, 5 ); outnl( z );
y0 := real_sub( x1, x0 ); real_output( z, y0, 10, 5 ); outnl( z );
y1 := real_mult( eps, x1 ); real_output( z, y1, 10, 5 ); outnl( z );
y0 := real_abs( y0 ); real_output( z, y0, 10, 5 ); outnl( z );
b := real_lt( y0, y1 );
if b then outstring( z, 'true ' )
else outstring( z, 'false ' ); outnl( z );
until
b;
real_sqrt := x0
end;
procedure real_output( var z : zone; r : real; positions, decimals : integer );
var
sign : boolean;
li10 : lint;
lf, li : lint;
i : integer;
begin
if lint_lt_zero( r.d ) then
begin
r.d := lint_neg( r.d );
r.c := lint_neg( r.c )
end;
if lint_lt_zero( r.c ) then
begin
sign := true;
r.c := lint_neg( r.c )
end
else
sign := false;
li := lint_div( r.c, r.d );
if lint_eq_zero( li ) and sign then
begin
for i := 1 to positions - decimals - 3 do outchar( z, ' ' );
outchar( z, '-' ); outchar( z, '0' )
end
else
begin
if sign then li := lint_neg( li );
lint_output( z, false, li, positions - decimals - 1 );
end;
outchar( z, '.' );
lf := lint_mod( r.c, r.d );
li := lint_from_integer( 1 ); li10 := lint_from_integer( 10 );
for i := 1 to decimals do li := lint_mult( li, li10 );
lint_output( z, true, lint_div( lint_mult( lf, li ), r.d ), decimals )
end;
var
eps : real;
procedure error( kind, where : integer );
begin
outnl( z );
outstring( z, ' error: ' );
outinteger( z, kind, 5 ); outinteger( z, where, 5 );
outnl( z );
outclose( z );
(* terminate the execution by provoking an exception: *)
kind := 0; kind := kind div kind
end;
begin
outopen( z, own.incname, sysvector( operatorsem ) );
outstring( z, 'sqrt table: ' ); outnl( z );
eps := real_div( real_from_integer( 1 ), real_from_integer( 100 ) );
outstring( z, 'eps: ' );
real_output( z, eps, 10, 6 );
outnl( z );
outinteger( z, 1, 3 ); outchar( z, ':' );
real_output( z, real_from_integer( 1 ), 10, 3 );
outnl( z );
for i := 2 to 10 do
begin
outinteger( z, i, 3 ); outchar( z, ':' );
real_output( z, real_sqrt( z, real_from_integer( i ) , eps ), 10, 3 );
outnl( z )
end;
outstring( z, 'end program ' ); outnl( z );
outclose( z )
end.
«eof»