1 { $Id: machar.p,v 2.2 1994/06/24 12:36:47 ceriel Exp $ }
3 procedure machar (var ibeta , it , irnd , ngrd , machep , negep , iexp,
4 minexp , maxexp : integer ; var eps , epsneg , xmin , xmax : real ) ;
7 procedure encaps(procedure p; procedure q(i:integer)); extern;
8 procedure trap(i:integer); extern;
10 procedure catch(i:integer);
12 begin if i=underflo then trapped:=true else trap(i) end;
18 { This subroutine is intended to determine the characteristics
19 of the floating-point arithmetic system that are specified
20 below. The first three are determined according to an
21 algorithm due to M. Malcolm, CACM 15 (1972), pp. 949-951,
22 incorporating some, but not all, of the improvements
23 suggested by M. Gentleman and S. Marovich, CACM 17 (1974),
24 pp. 276-277. The version given here is for single precision.
26 Latest revision - October 1, 1976.
29 Argonne National Laboratory
31 Revised for Pascal - R. A. Freak
32 University of Tasmania
36 ibeta is the radix of the floating-point representation
37 it is the number of base ibeta digits in the floating-point
39 irnd = 0 if the arithmetic chops,
40 1 if the arithmetic rounds
41 ngrd = 0 if irnd=1, or if irnd=0 and only it base ibeta
42 digits participate in the post normalization shift
43 of the floating-point significand in multiplication
44 1 if irnd=0 and more than it base ibeta digits
45 participate in the post normalization shift of the
46 floating-point significand in multiplication
47 machep is the exponent on the smallest positive floating-point
48 number eps such that 1.0+eps <> 1.0
49 negeps is the exponent on the smallest positive fl. pt. no.
50 negeps such that 1.0-negeps <> 1.0, except that
51 negeps is bounded below by it-3
52 iexp is the number of bits (decimal places if ibeta = 10)
53 reserved for the representation of the exponent of
54 a floating-point number
55 minexp is the exponent of the smallest positive fl. pt. no.
57 maxexp is the exponent of the largest finite floating-point
59 eps is the smallest positive floating-point number such
60 that 1.0+eps <> 1.0. in particular,
62 epsneg is the smallest positive floating-point number such
63 that 1.0-eps <> 1.0 (except that the exponent
64 negeps is bounded below by it-3). in particular
66 xmin is the smallest positive floating-point number. in
67 particular, xmin = ibeta ** minexp
68 xmax is the largest finite floating-point number. in
69 particular xmax = (1.0-epsneg) * ibeta ** maxexp
70 note - on some machines xmax will be only the
71 second, or perhaps third, largest number, being
72 too small by 1 or 2 units in the last digit of
77 i , iz , j , k , mx : integer ;
78 a , b , beta , betain , betam1 , one , y , z , zero : real ;
87 determine ibeta,beta ala Malcolm
89 while ( ( ( a + one ) - a ) - one = zero ) do begin
92 while ( ( a + b ) - a = zero ) do begin
95 ibeta := trunc ( ( a + b ) - a );
97 betam1 := beta - one ;
99 determine irnd,ngrd,it
101 if ( ( a + betam1 ) - a = zero ) then irnd := 0 ;
107 end until ( ( ( a + one ) - a ) - one <> zero ) ;
109 determine negep, epsneg
114 for i := 1 to negep do begin
118 while ( ( one - a ) - one = zero ) do begin
125 determine machep, eps
128 while ( ( one + a ) - one = zero ) do begin
130 machep := machep + 1 ;
137 if(( irnd = 0) and((( one + eps) * one - one) <> zero)) then
140 determine iexp, minexp, xmin
142 loop to determine largest i such that
145 exit from loop is signall by an underflow
148 betain := one / beta ;
162 determine k such that (1/beta)**k does not underflow
167 for j := 1 to i do begin
173 if ( ibeta = 10 ) then begin
175 for decimal machines only }
178 while ( k >= iz ) do begin
187 loop to construct xmin
188 exit from loop is signalled by an underflow
196 { determine maxexp, xmax
198 if ( ( mx <= k + k - 3 ) and ( ibeta <> 10 ) ) then begin
202 maxexp := mx + minexp ;
203 { adjust for machines with implicit leading
204 bit in binary significand and machines with
205 radix point at extreme right of significand
207 i := maxexp + minexp ;
208 if ( ( ibeta = 2 ) and ( i = 0 ) ) then maxexp := maxexp - 1 ;
209 if ( i > 20 ) then maxexp := maxexp - 3 ;
210 xmax := one - epsneg ;
211 if ( xmax * one <> xmax ) then xmax := one - beta * epsneg ;
212 xmax := ( xmax * betain * betain * betain ) / xmin ;
213 i := maxexp + minexp + 3 ;
214 if ( i > 0 ) then begin
216 for j := 1 to i do begin
217 xmax := xmax * beta ;