home *** CD-ROM | disk | FTP | other *** search
- EXTERNAL flptdemo :: basicops(1);
-
- {-------------------------------------------------------------------}
- { }
- { PROGRAM TITLE : EXTENDED PRECISION FLOATING POINT PACKAGE }
- { BASIC OPERATIONS MODULE }
- { }
- { WRITTEN BY : LANFRANCO EMILIANI }
- { MAURITS DE BRAUWWEG 11 }
- { 2597-KD DEN HAAG }
- { THE NETHERLANDS }
- { }
- { INITIAL ISSUE : DECEMBER 1982 }
- { }
- { PRESENT ISSUE : DECEMBER 1982 }
- { }
- { DOCUMENTED IN : FILE FLPTPACK.DOC }
- { }
- {-------------------------------------------------------------------}
-
- {$F-,R- to increase the speed of execution }
-
- function absol(u : newreal) : newreal;
- begin
- absol.s := plus;
- absol.f := u.f;
- absol.e := u.e
- end;
-
- function isequal(u, v : newreal) : boolean;
- var
- i : integer;
- begin
- if ((u.s = plus) and (v.s = minus)) or
- ((u.s = minus) and (v.s = plus)) or
- (u.e <> v.e)
- then isequal := false
- else
- begin
- i := 1;
- while (u.f[i] = v.f[i]) and (i < n) do i:= i + 1;
- if u.f[i] = v.f[i] then isequal := true else isequal := false
- end;
- end;
-
- function isgreater(u, v : newreal) : boolean;
- var
- i : integer;
- begin
- if (u.s = plus) and (v.s = minus) then isgreater := true
- else
- begin
- if (u.s = minus) and (v.s = plus) then isgreater := false
- else {like signs}
- begin
- if u.e > v.e then isgreater := true
- else
- begin
- if u.e < v.e then isgreater := false
- else {like signs and exponents}
- begin
- i := 1;
- while (u.f[i] = v.f[i]) and (i < n) do i := i + 1;
- if u.f[i] > v.f[i] then isgreater := true else isgreater := false
- end
- end
- end
- end
- end;
-
- function islower(u, v : newreal) : boolean;
- begin
- if isgreater(u, v) or isequal(u, v) then islower := false
- else islower := true
- end;
-
- function iseqgreat(u, v : newreal) : boolean;
- begin
- if islower(u, v) then iseqgreat := false else iseqgreat := true
- end;
-
- function iseqlower(u, v : newreal) : boolean;
- begin
- if isgreater(u,v) then iseqlower := false else iseqlower := true
- end;
-
- function isinteger(u : newreal) : boolean;
- {WARNING : the following listing is only valid for n <= 6}
- var
- i : integer;
- begin
- if ((u.e > 0) and (u.e < 129)) or (u.e > (128 + n)) then isinteger := false
- else
- begin
- i := n;
- while (u.f[i] = 0) and (i > 0) do i := i - 1;
- case u.e of
- 0 : if i = 0 then isinteger := true else isinteger := false;
- 129 : if i = 1 then isinteger := true else isinteger := false;
- 130 : if i = 2 then isinteger := true else isinteger := false;
- 131 : if i = 3 then isinteger := true else isinteger := false;
- 132 : if i = 4 then isinteger := true else isinteger := false;
- 133 : if i = 5 then isinteger := true else isinteger := false;
- 134 : if i = 6 then isinteger := true else isinteger := false
- end {case}
- end
- end;
-
-
- function intadd(u, v : newinteger) : newinteger;
- {called by add}
- var
- carry : 0..1;
- j : integer;
- result : newinteger;
- cplmt : newinteger;
- begin
- carry := 0;
- if u.s = v.s then {like signs}
- begin
- intadd.s := u.s;
- for j := n downto 1 do
- intadd.f[j] := byteadd(carry, u.f[j], v.f[j]);
- intadd.f[0] := carry
- end
- else {unlike signs}
- begin
- if u.s = plus then
- for j := n downto 1 do
- result.f[j] := bytesub(carry, u.f[j], v.f[j])
- else
- for j := n downto 1 do
- result.f[j] := bytesub(carry, v.f[j], u.f[j]);
- if carry = 0 then
- begin
- result.f[0] := carry;
- result.s := plus
- end
- else
- begin
- result.s := minus;
- carry := 0;
- for j:= n downto 1 do
- cplmt.f[j] := bytesub(carry, 0, result.f[j]);
- cplmt.f[0] := 0;
- result.f := cplmt.f
- end;
- intadd := result
- end;
- end;
-
- procedure increm (var carry : carrytyp; var u : fraction);
- {called by add and by divde}
- var
- i : integer;
- begin
- carry := 0;
- u[n] := byteadd(carry, u[n], 1);
- if carry = 1 then
- begin
- for i := (n-1) downto 1 do u[i] := byteadd(carry, u[i], 0);
- if carry =1 then
- begin
- for i := (n-1) downto 1 do u[i+1] := u[i];
- u[1] := 1
- end;
- end;
- end;
-
-
- function add(u, v : newreal) : newreal;
- var
- aux : newreal;
- shift, exponent : integer;
- i, j : integer;
- dummy1, dummy2, dummy3 : newinteger;
- temp : byte;
- carry : carrytyp;
-
- begin
- shift := u.e - v.e;
- if shift < 0 then
- begin
- aux := u; u := v; v := aux; shift := -shift
- end;
- if shift >= (n+2) then add := u
- else
- begin
- exponent := u.e;
- v.f[0] := 0;
- i := 0;
- while i <> shift do
- begin
- for j := n downto 1 do v.f[j] := v.f[j-1];
- i := i + 1
- end;
- dummy1.s := u.s;
- dummy1.f := u.f;
- dummy2.s := v.s;
- dummy2.f := v.f;
- dummy3 := intadd(dummy1, dummy2);
- add.s := dummy3.s;
- if dummy3.f[0] <> 0 then
- begin
- temp := dummy3.f[n];
- for j := (n-1) downto 0 do
- dummy3.f[j+1] := dummy3.f[j];
- dummy3.f[0] := 0;
- exponent := exponent + 1;
- {rounding if required}
- if (mode = rounded) and ((temp > 128) or
- ((temp = 128) and odd(dummy3.f[n] + 1))) then
- begin
- increm(carry, dummy3.f);
- if carry = 1 then
- exponent := exponent + 1
- end;
- end
- else
- begin
- {remove leading zeros}
- i := 1;
- while (dummy3.f[1] = 0) and (i <> n) do
- begin
- for j := 1 to (n-1) do
- dummy3.f[j] := dummy3.f[j+1];
- dummy3.f[n] := 0;
- exponent := exponent - 1;
- i := i + 1
- end;
- {the result is zero}
- if dummy3.f[1] = 0 then
- begin
- add.s := plus;
- exponent := 0
- end;
- end;
- dummy3.f[0] := 0;
- add.f := dummy3.f;
- if (exponent>=0) and (exponent<=255) then add.e:=exponent
- else
- begin
- if exponent < 0 then
- begin
- writeln('SUM OR DIFF EXPONENT UNDERFLOW !');
- add.s := plus;
- for i := 0 to n do add.f[i] := 0;
- add.e := 0
- end
- else
- begin
- writeln('SUM OR DIFF EXPONENT OVERFLOW !');
- add.f[0] := 0;
- for i := 1 to n do add.f[i] := 255;
- add.e := 255
- end;
- end;
- end;
- end;
-
- function sub(u, v : newreal) : newreal;
- begin
- if v.s = plus then v.s := minus else v.s := plus;
- sub := add(u, v)
- end;
-
- procedure incr (var carry : carrytyp; var u : double_fraction);
- {called by mult}
- var
- i : integer;
- begin
- carry := 0;
- u[n] := byteadd(carry, u[n], 1);
- if carry = 1 then
- begin
- for i := (n-1) downto 1 do u[i] := byteadd(carry, u[i], 0);
- if carry =1 then
- begin
- for i := (n-1) downto 1 do u[i+1] := u[i];
- u[1] := 1
- end;
- end;
- end;
-
-
- function multp(u, v : newreal) : newreal;
- var
- aux : double_fraction;
- k : byte;
- i, j, exponent : integer;
- carry : carrytyp;
- begin
- if u.s = v.s then multp.s := plus else multp.s := minus;
- exponent := u.e + v.e - 128;
- for j := 0 to twicen do aux[j] := 0;
- for j := n downto 1 do
- begin
- k := 0;
- for i := n downto 1 do bytemul(k, aux[i+j], u.f[i], v.f[j]);
- aux[j] := k
- end;
- {remove leading zeros}
- j := 1;
- while (aux[1] = 0) and (j <> twicen) do
- begin
- for i := 1 to (twicen - 1) do aux[i] := aux[i+1];
- aux[twicen] := 0;
- exponent := exponent - 1;
- j := j + 1
- end;
- if aux[1] = 0 then {the result is zero}
- begin
- multp.s := plus;
- exponent := 0
- end;
- {rounding if required}
- if (mode = rounded) and ((aux[n+1] > 128) or
- ((aux[n+1] = 128) and odd(aux[n] + 1))) then
- begin
- incr(carry, aux);
- if carry = 1 then exponent := exponent + 1
- end;
- for i := 0 to n do multp.f[i] := aux[i];
- if (exponent >= 0) and (exponent <= 255) then multp.e := exponent
- else
- begin
- if exponent < 0 then
- begin
- writeln('PRODUCT EXPONENT UNDERFLOW !');
- multp.s := plus;
- for i := 0 to n do multp.f[i] := 0;
- multp.e := 0
- end
- else
- begin
- writeln('PRODUCT EXPONENT OVERFLOW !');
- multp.f[0] := 0;
- for i := 1 to n do multp.f[i] := 255;
- multp.e := 255
- end;
- end;
- end;
-
- procedure dvd(u : double_fraction; v : fraction; var q, r : fraction);
- {called by divde and by modu}
- var
- aa : fraction;
- d : 1..128;
- k, newk : byte;
- kk : carrytyp;
- i, j : integer;
- t1 : real;
- qu : byte;
- begin
- d := 256 div (v[1] + 1);
- if d = 1 then u[0] := 0 else
- begin {normalisation}
- k := 0;
- for i := twicen downto 1 do u[i] := byt1mul(k, u[i], d);
- u[0] := k;
- k := 0;
- for i := n downto 1 do v[i] := byt1mul(k, v[i], d);
- end; {normalisation}
- v[0] := 0;
- for j := 0 to n do
- begin
- if u[j] >= v[1] then qu := 255
- else
- t1 := (u[j]*256.0 + u[j+1]) / v[1];
- if t1 < 254.5 then qu := round(t1) else qu := 255;
- while (v[1]*256.0 + v[2]*1.0)*qu >
- (u[j]*0.655360E5 + u[j+1]*256.0 + u[j+2]*1.0) do
- qu := qu - 1;
- k := 0;
- for i := n downto 1 do aa[i] := byt1mul(k, qu, v[i]);
- aa[0] := k;
- kk := 0;
- for i := n downto 0 do u[j+i] := bytesub(kk, u[j+i], aa[i]);
- q[j] := qu;
- if kk = 1 then
- begin
- q[j] := qu - 1;
- kk := 0;
- for i := n downto 0 do u[j+i] := byteadd(kk, u[j+i], v[i]);
- end;
- end;
- if d = 1 then for i := 1 to n do r[i] := u[i+n]
- else
- begin
- k := 0;
- for i := 1 to n do
- begin
- byt1div(newk, r[i], k, u[i+n], d);
- k := newk
- end;
- end;
- end;
-
-
- function divde(u, v : newreal) : newreal;
- label 999;
- var
- i, j : integer;
- exponent: integer;
- alfa : double_fraction;
- gamma, delta : fraction;
- carry : carrytyp;
- begin
- if v.f[1] = 0 then
- begin
- if u.f[1] <> 0 then
- begin
- writeln('ATTEMPTED DIVISION BY ZERO !');
- {quotient set to max positive value}
- divde.s := plus;
- divde.f[0] := 0;
- for i := 1 to n do divde.f[i] := 255;
- divde.e := 255
- end
- else
- begin
- writeln('ATTEMPTED DIVISION OF ZERO BY ZERO !');
- {quotient set to plus one}
- divde.s := plus;
- divde.f[0] := 0;
- divde.f[1] := 1;
- for i := 2 to n do divde.f[i] := 0;
- divde.e := 129
- end;
- goto 999
- end;
- if u.s = v.s then divde.s := plus else divde.s := minus;
- exponent := u.e - v.e + 128;
- for i := 1 to n do alfa[i] := u.f[i];
- for i := (n+1) to twicen do alfa[i] := 0;
- dvd(alfa, v.f, gamma, delta);
- if gamma[0] <> 0 then
- begin
- for i := (n-1) downto 0 do gamma[i+1] := gamma[i];
- gamma[0] := 0;
- exponent := exponent + 1
- end
- else
- begin
- {remove leading zeros}
- i := 1;
- while (gamma[1] = 0) and (i <> n) do
- begin
- for j := 0 to (n-1) do gamma[j] := gamma[j+1];
- gamma[n] := 0;
- exponent := exponent - 1;
- i := i + 1
- end;
- if gamma[1] = 0 then {the result is zero}
- begin
- divde.s := plus;
- exponent := 0
- end;
- end;
- {rounding if required}
- if mode = rounded then
- begin
- {doubling the remainder}
- carry := 0;
- for i := n downto 1 do delta[i] := byt1mul(carry, delta[i], 2);
- delta[0] := carry;
- {comparing the divisor with twice the remainder}
- i := 0;
- v.f[0] := 0;
- while (v.f[i] = delta[i]) and (i < n) do i := (i+1);
- if (v.f[i]<delta[i]) or ((v.f[i]=delta[i]) and odd(gamma[n]+1))
- then
- begin
- increm(carry, gamma);
- if carry = 1 then exponent := exponent + 1
- end;
- end;
- divde.f := gamma;
- if (exponent >= 0) and (exponent <= 255) then divde.e := exponent
- else
- begin
- if exponent < 0 then
- begin
- writeln('QUOTIENT EXPONENT UNDERFLOW !');
- divde.s := plus;
- for i := 0 to n do divde.f[i] := 0;
- divde.e := 0
- end
- else
- begin
- writeln('QUOTIENT EXPONENT OVERFLOW !');
- divde.f[0] := 0;
- for i := 1 to n do divde.f[i] := 255;
- divde.e := 255
- end;
- end;
- 999 :
- end;
-
- function modu(u, v : newreal) : newreal;
- label 9999;
- var
- zero, aux, w : newreal;
- i, j, k, exponent, limit: integer;
- alfa : double_fraction;
- gamma, delta : fraction;
- begin
- with zero do begin s := plus; for i := 0 to n do f[i] := 0; e := 0 end;
- if (v.f[1] = 0) or (v.s = minus) then
- begin
- writeln('ATTEMPTED COMPUTING REMAINDER FOR ZERO OR NEG DIVISOR');
- writeln(' VALUE OF MODULO SET TO ZERO');
- modu := zero
- end
- else
- begin
- if (u.f[1] = 0) or (iseqlower(absol(u), v)) then modu := zero
- else
- begin
- aux := u;
- exponent := v.e;
- {start the division and then, for (u.e - v.e) div n times,
- continue dividing after replacement of the dividend by the
- remainder of the previous division}
- limit := (u.e - v.e) div n;
- for k := 0 to limit do
- begin
- for i := 1 to n do alfa[i] := aux.f[i];
- for i := (n+1) to twicen do alfa[i] := 0;
- delta[0] := 0; {value not set within divd}
- dvd(alfa, v.f, gamma, delta);
- {remove leading zeros}
- i := 1;
- while (delta[1] = 0) and (i <> n) do
- begin
- for j := 0 to (n-1) do delta[j] := delta[j+1];
- delta[n] := 0;
- exponent := exponent - 1;
- i := i + 1
- end;
- if delta[1] = 0 then {the result is zero}
- begin
- modu := zero;
- goto 9999
- end;
- aux.f := delta;
- if exponent >= 0 then aux.e := exponent
- else
- begin
- writeln('MODULO EXPONENT UNDERFLOW !');
- modu := zero;
- goto 9999
- end;
- end;
- limit := (u.e - v.e) mod n;
- aux.e := aux.e + limit;
- {as long as the remainder exceeds the divisor keep subtracting
- the divisor from it}
- aux := absol(aux); {to speed up the steps which follow}
- w := v;
- w.e := w.e + limit - 1;
- repeat
- while isgreater(aux, w) do aux := sub(aux, w);
- if w.e > 0 then w.e := w.e - 1;
- limit := limit - 1;
- until limit = - 1;
- aux.s := u.s; {to set the correct sign again}
- modu := aux
- end
- end;
- 9999:
- end;
-
-
- function putnreal(inp : extdatum) : newreal;
- {called by do_read}
- var
- carry : digits;
- i, j, k : integer;
- t : integer;
- u : array[1..3] of digits;
- v : array[1..nn] of digits;
- w : array[1..(nn+3)] of digits;
- ten, one, pointone, aaa, auxiliary : newreal;
-
- begin
- for j := 1 to nn do v[j] := inp.f[j];
- u[1] := 2; u[2] := 5; u[3] := 6;
- aaa.s := inp.s;
- aaa.f[0] := 0;
- for i := 1 to n do
- begin
- {multiplication}
- for j := 1 to (nn+3) do w[j] := 0;
- for j := nn downto 1 do
- begin
- carry := 0;
- for k := 3 downto 1 do
- begin
- t := u[k]*v[j] + w[k+j] + carry;
- w[k+j] := t mod 10;
- carry := t div 10
- end;
- w[j] := carry
- end;
- {getting the byte}
- aaa.f[i] := w[1]*100 + w[2]*10 + w[3];
- {left shift}
- for j := 1 to 3 do
- begin
- for k := 1 to (nn+2) do w[k] := w[k+1];
- w[nn] := 0
- end;
- {re-assignment}
- for j := 1 to nn do v[j] := w[j]
- end;
- aaa.e := 128;
- {finalizing the transformation}
- if inp.e = 0 then
- {apart from normalisation putnreal can be set equal to aaa}
- begin
- {remove leading zeros}
- {this would not be necessary if the calling procedure is do_read}
- j := 1;
- while (aaa.f[1] = 0) and (j <> n) do
- begin
- for i := 1 to (n - 1) do aaa.f[i] := aaa.f[i + 1];
- aaa.f[n] := 0;
- aaa.e := aaa.e - 1;
- j := j + 1
- end;
- {the result is zero}
- if aaa.f[1] = 0 then
- begin
- aaa.s := plus;
- aaa.e := 0
- end;
- putnreal := aaa
- end
- else
- begin
- with one do
- begin
- s := plus; f[0] := 0; f[1] := 1;
- for i := 2 to n do f[i] := 0;
- e := 129 end;
- auxiliary := one;
- if inp.e > 0 then
- begin
- with ten do
- begin
- s := plus; f[0] := 0; f[1] := 10;
- for i := 2 to n do f[i] := 0;
- e := 129 end;
- for i := 1 to inp.e do
- auxiliary := multp(auxiliary, ten)
- end
- else {exponent < 0}
- begin
- with pointone do
- begin
- s := plus; f[0] := 0; f[1] := 25;
- for i := 2 to n do f[i] := 153;
- if mode = rounded then f[n] := 154;
- e := 128 end;
- for i := inp.e to -1 do
- auxiliary := multp(auxiliary, pointone);
- end;
- putnreal := multp(aaa, auxiliary)
- end;
- end;
-
-
- procedure do_read(var u : extdatum; var v : newreal);
- const
- z = 48; {ord('0')}
- var
- ch : char;
- exposign : signtype;
- i, j : integer;
- temp, exponent : integer;
- begin
- read(ch);
- {skipping leading blanks}
- while ch = ' ' do read(ch);
- if ch = '-' then
- begin
- u.s := minus;
- read(ch)
- end
- else
- begin
- u.s := plus;
- if ch = '+' then read(ch)
- end;
- while not (ch in ['0'..'9']) do
- begin
- writeln('INPUT STRING NOT FOUND : PLEASE TRY AGAIN.');
- read(ch)
- end;
- {getting the fraction}
- exponent := 0;
- u.f[0] := 0;
- i := 1;
- {skipping leading zeros}
- while ch = '0' do read(ch);
- while (ch in ['0'..'9']) and (i <= prec) do
- begin
- u.f[i] := ord(ch) - z;
- exponent := exponent + 1;
- i := i + 1;
- read(ch)
- end;
- if ch = '.' then
- begin
- read(ch);
- {skipping further non significant digits}
- if exponent = 0 then
- begin
- while ch = '0' do
- begin
- read(ch);
- exponent := exponent - 1
- end
- end;
- while (ch in ['0'..'9']) and (i <= prec) do
- begin
- u.f[i] := ord(ch) - z;
- i := i + 1;
- read(ch)
- end
- end;
- for j := i to nn do u.f[j] := 0;
- if (ch in ['0'..'9']) then writeln(
- 'INPUT STRING TOO LONG : DIGITS BEYOND THE ',prec:1,'TH DIGIT ARE IGNORED');
- writeln('
- INPUT STRING CONSISTS OF A ',u.s:1,' SIGN AND ',(i-1):1,' DIGIT(S).');
- {skipping further digits}
- while (ch in ['0'..'9']) do read(ch);
- if (ch = 'E') or (ch = 'e') then
- begin
- read(ch);
- temp := 0;
- if ch = '-' then
- begin
- exposign := minus;
- read(ch)
- end
- else
- begin
- exposign := plus;
- if ch = '+' then read(ch)
- end;
- while not (ch in ['0'..'9']) do
- begin
- writeln('EXPONENT NOT FOUND : PLEASE TRY AGAIN.');
- read(ch)
- end;
- temp := ord(ch) - z;
- i := 1;
- read(ch);
- while (ch in ['0'..'9']) and (i < 3) do
- begin
- temp := 10*temp + ord(ch) - z;
- i := i + 1;
- read(ch)
- end;
- if (ch in ['0'..'9']) then
- writeln('
- EXPONENT STRING TOO LONG : DIGITS BEYOND THE 3RD ARE IGNORED.');
- writeln('
- EXPONENT CONSISTS OF A ',exposign:1,' SIGN AND ', i:1, ' DIGIT(S).');
- {skipping further digits}
- while (ch in ['0'..'9']) do read(ch);
- if exposign = minus then exponent := exponent - temp
- else exponent := exponent + temp
- end;
- u.e := exponent;
- v := putnreal(u)
- end;
-
-
- procedure inc(i : integer; var u : long_fraction);
- {called by auxmult}
- begin
- if u[i] <> 9 then u[i] := u[i] + 1
- else
- begin
- u[i] := 0;
- inc(i-1, u)
- end;
- end;
-
-
- function auxmult(u, v : extdatum) : extdatum;
- {called by getnreal}
- var
- aux : long_fraction;
- k : digits;
- t : 0..maxint;
- i, j, exponent : integer;
- begin
- if u.s = v.s then auxmult.s := plus else auxmult.s := minus;
- exponent := u.e + v.e;
- for j := 1 to twicenn do aux[j] := 0;
- for j := nn downto 1 do
- begin
- k := 0;
- for i := nn downto 1 do
- begin
- t := u.f[i]*v.f[j] + aux[i+j] + k;
- aux[i+j] := t mod 10;
- k := t div 10
- end;
- aux[j] := k;
- end;
- {remove leading zeros}
- j := 1;
- while (aux[1] = 0) and (j <> twicenn) do
- begin
- for i := 0 to (twicenn - 1) do aux[i] := aux[i+1];
- aux[twicenn] := 0;
- exponent := exponent - 1;
- j := j + 1
- end;
- {rounding if required}
- if (mode = rounded) and (aux[nn+1] > 5) then
- begin
- inc(nn, aux);
- if aux[0] <> 0 then
- begin
- for j := (twicenn - 1) downto 0 do aux[j+1] := aux[j];
- aux[0] := 0;
- exponent := exponent + 1
- end;
- end;
- auxmult.f[0] :=0;
- for i := 1 to nn do auxmult.f[i] := aux[i];
- auxmult.e := exponent;
- end;
-
-
- function getnreal(inp : newreal) : extdatum;
- {WARNING : the following listing is only valid for n <= 6}
- {called by do_write}
- var
- carry : digits;
- i, j, k : integer;
- t, shift, exponent : integer;
- u : array[1..3] of digits;
- v, aa, bb, cc, dd, ee, ff : array[1..nn] of digits;
- w, aaa, bbb : array[0..(nn+3)] of digits;
- ccc, auxiliary, twohun56, one, oneover256 : extdatum;
- begin
- {(1/256)*10^2}
- aa[1]:=3; aa[2]:=9; aa[3]:=0; aa[4]:=6;
- aa[5]:=2; aa[6]:=5;
- for i := 7 to nn do aa[i] := 0;
- {(1/256^2)*10^4}
- bb[1]:=1; bb[2]:=5; bb[3]:=2; bb[4]:=5;
- bb[5]:=8; bb[6]:=7; bb[7]:=8; bb[8]:=9;
- bb[9]:=0; bb[10]:=6; bb[11]:=2; bb[12]:=5;
- for i := 13 to nn do bb[i] := 0;
- {(1/256^3)*10^7}
- cc[1]:=5; cc[2]:=9; cc[3]:=6; cc[4]:=0;
- cc[5]:=4; cc[6]:=6; cc[7]:=4; cc[8]:=4;
- cc[9]:=7; cc[10]:=7; cc[11]:=5; cc[12]:=3;
- cc[13]:=9;
- if mode=rounded then cc[14]:=1 else cc[14]:=0;
- {(1/256^4)*10^9}
- dd[1]:=2; dd[2]:=3; dd[3]:=2; dd[4]:=8;
- dd[5]:=3; dd[6]:=0; dd[7]:=6; dd[8]:=4;
- dd[9]:=3; dd[10]:=6; dd[11]:=5; dd[12]:=3;
- dd[13]:=8;
- if mode=rounded then dd[14]:=7 else dd[14]:=6;
- {(1/256^5)*10^12}
- ee[1]:=9; ee[2]:=0; ee[3]:=9; ee[4]:=4;
- ee[5]:=9; ee[6]:=4; ee[7]:=7; ee[8]:=0;
- ee[9]:=1; ee[10]:=7; ee[11]:=7; ee[12]:=2;
- ee[13]:=9;
- if mode=rounded then ee[14]:=3 else ee[14]:=2;
- {(1/245^6)*10^14}
- ff[1]:=3; ff[2]:=5; ff[3]:=5; ff[4]:=2;
- ff[5]:=7; ff[6]:=1; ff[7]:=3; ff[8]:=6;
- ff[9]:=7; ff[10]:=8; ff[11]:=8; ff[12]:=0;
- ff[13]:=0; ff[14]:=5;
- for i := 0 to (nn+3) do bbb[i] := 0;
- aaa[0] := 0;
- for i := 1 to n do
- begin
- u[1] := inp.f[i] div 100;
- u[2] := (inp.f[i] mod 100) div 10;
- u[3] := (inp.f[i] mod 100) mod 10;
- case i of
- 1 : begin v := aa; shift := 0 end;
- 2 : begin v := bb; shift := 2 end;
- 3 : begin v := cc; shift := 5 end;
- 4 : begin v := dd; shift := 7 end;
- 5 : begin v := ee; shift := 10 end;
- 6 : begin v := ff; shift := 12 end;
- end; {case}
- {multiplication}
- for j := 1 to (nn+3) do w[j] := 0;
- for j := nn downto 1 do
- begin
- carry := 0;
- for k := 3 downto 1 do
- begin
- t := u[k]*v[j]+w[k+j]+carry;
- w[k+j] := t mod 10;
- carry := t div 10
- end;
- w[j] := carry
- end;
- {shift to the right}
- for j := 1 to shift do
- begin
- for k := nn+2 downto 1 do w[k+1] := w[k];
- w[1] := 0
- end;
- {addition}
- carry := 0;
- for j := nn+3 downto 1 do
- begin
- aaa[j] := (bbb[j] + w[j] + carry) mod 10;
- carry := (bbb[j] + w[j] + carry) div 10
- end;
- aaa[0] := carry + aaa[0]; {WARNING : valid only for n <= 9}
- bbb := aaa
- end;
- exponent := 1;
- {conditional shift to the right}
- if aaa[0] <> 0 then
- begin
- for k := nn+2 downto 0 do aaa[k+1] := aaa[k];
- aaa[0] := 0;
- exponent := exponent + 1
- end
- else
- begin
- {remove leading zeros}
- j := 1;
- while (aaa[1] = 0) and (j <> nn+3) do
- begin
- for i := 1 to nn+2 do aaa[i] := aaa[i+1];
- aaa[nn+3] := 0;
- exponent := exponent - 1;
- j := j + 1
- end;
- end;
- ccc.s := inp.s;
- for i := 0 to nn do ccc.f[i] := aaa[i];
- ccc.e := exponent;
- {the result is zero}
- if ccc.f[1] = 0 then
- begin
- ccc.s := plus;
- ccc.e := 1 {to display an exponent of zero equal to 0}
- end;
- if (inp.e = 128) or (ccc.f[1] = 0) then getnreal := ccc
- else
- begin
- one.s := plus;
- one.f[0] := 0;
- one.f[1] := 1;
- for i := 2 to nn do one.f[i] := 0;
- one.e := 1;
- auxiliary := one;
- if inp.e > 128 then
- begin
- twohun56.s := plus;
- twohun56.f[0] := 0;
- twohun56.f[1] := 2;
- twohun56.f[2] := 5;
- twohun56.f[3] := 6;
- for i := 4 to nn do twohun56.f[i] := 0;
- twohun56.e := 3;
- for i := 129 to inp.e do
- auxiliary := auxmult(auxiliary, twohun56)
- end
- else {exponent < 128}
- begin
- with oneover256 do
- begin s := plus; f[0] := 0; f[1] := 3;
- f[2] := 9; f[3] := 0; f[4] := 6; f[5] := 2;
- f[6] := 5;
- for j := 7 to nn do f[j] := 0;
- e := -2 end;
- for i := inp.e to 127 do
- auxiliary := auxmult(auxiliary, oneover256);
- end;
- getnreal := auxmult(ccc, auxiliary)
- end;
- end;
-
- procedure do_write(u : newreal);
- var
- aux : extdatum;
- i : integer;
- begin
- aux := getnreal(u);
- if aux.s = plus then write('+') else write('-');
- write(aux.f[1]:1, '.');
- for i := 2 to prec do write(aux.f[i]:1);
- write('E');
- if (aux.e - 1) < 0 then write('-') else write('+');
- if abs(aux.e - 1) < 10 then write('0');
- write(abs(aux.e - 1):1)
- end;
-
- {$F+,R+ }
- . {end of the module basicops}
-