Artifact a0d04daf63e1b2e71e54edfff34ddc307ab9e1d297f7f6ca758679fa476eb1a8:
- File
psl-1983/3-1/tests/write-real-in-psl.red
— part of check-in
[eb17ceb7f6]
at
2020-04-21 19:40:01
on branch master
— Add Reduce 3.0 to the historical section of the archive, and some more
files relating to version sof PSL from the early 1980s. Thanks are due to
Paul McJones and Nelson Beebe for these, as well as to all the original
authors.git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/historical@5328 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 5504) [annotate] [blame] [check-ins using] [more...]
- File
psl-1983/tests/write-real-in-psl.red
— part of check-in
[eb17ceb7f6]
at
2020-04-21 19:40:01
on branch master
— Add Reduce 3.0 to the historical section of the archive, and some more
files relating to version sof PSL from the early 1980s. Thanks are due to
Paul McJones and Nelson Beebe for these, as well as to all the original
authors.git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/historical@5328 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 5504) [annotate] [blame] [check-ins using]
% WRITE-REAL.RED - Procedure to write a floating point number % Author: Martin Griss % Date: ~July 1982. % Notes by Maguire on 27.7.82: % Original version will use ~18K bytes for it's tables on the Apollo % due to the large exponent allowed. % See the common lisp manual, for names for base-B operations; % and constants for a re-write of this, to handle rounding etc. % Algorithm: By searching a table of powers of 10, previously % set up in a vector, determine % the Exponent and Mantissa of the given Float. % Then convert the mantissa to a pair of integers % and finally assembly the printed form as a string Fluid '(FltZero!* % Representation of 0.0 FltTen!* % 10.0 FltExponents % vector of (10^n) MinFltExponent % range of Exponents in table MaxFltExponent MaxFlt MinFlt MaxFltDigits % Maximum number of digits of precision FltDigits % Digits 0.0 ... 9.0 ); Procedure InitWriteFloats(MinEx,MaxEx,NDig); % Declare Maximum Number of Exponents and Digits Begin scalar Flt1,Flt!.1; FltZero!* := Float(0); Flt1 := Float(1); FltTen!* :=Float(10); Flt!.1 := Flt1/FltTen!*; MinFltExponent :=MinEx; MaxFltExponent:=MaxEx; NumberOfExponents := MaxEx-MinEx; % For UpLim on vector. MaxFltDigits:=Ndig; FltDigits:=MkVect 9; For I:=0:9 do FltDigits[I]:=Float I; FltExponents:=MkVect(NumberOfExponents); FltExponents[-MinEx]:=Flt1; FltExponents[1-Minex]:=FltTen!*; FltExponents[-1-Minex]:=Flt!.1; For i:=2-Minex:NumberOfExponents do FltExponents[i] := FltTen!* * FltExponents[i-1]; For i:=-2-MinEx Step -1 Until 0 do FltExponents[i] := Flt!.1 * FltExponents[i+1]; MinFlt := FltExponents[0]; MaxFlt := FltExponents[NumberOfExponents]; end; InitWriteFloats(-10,10,10); Procedure FindExponent(Flt); % return Exponent as Integer % First reduce Flt to table range then search. % Should Be Primitive, and done in Appropriate Float Base (2, or 16?) If Flt=FltZero!* then 0 else if Flt <FltZero!* then FindExponent(-Flt) else Begin scalar N; If Flt >= MaxFlt then return(MaxFltExponent+FindExponent(Flt/MaxFlt)); If Flt <= MinFlt then return(MinFltExponent+FindExponent(Flt/MinFlt)); N:=0; While N < NumberOfExponents and FltExponents[N] < Flt do N:=N+1; Return (N+MinFltExponent); End; Procedure FindMantissa(Flt); % return Mantissa as a (signed)float in [0.0 ..1.0) Flt/FloatPower10(FindExponent(Flt)); Procedure FloatPower10(n); % Returns 1FltZero!*^n, using table If N>MaxFltExponent then MaxFlt*FloatPower10(n-MaxFltExponent) else if N<MinFltExponent then MinFlt*FloatPower10(n-MinFltExponent) else FltExponents[n-MinFltExponent]; Procedure Flt2String(Flt); ScaledFloat2String(Flt,MaxFltDigits,0,-3,3); Procedure ScaledFloat2String(Flt,Ndigits,Scale, MinNice,MaxNice); % "print" a float, either in IIII.FFFF format, or SS.FFFFFeN % First format, if MinNice <=N<=MaxNice % ss controlled by Scale if second chosen % Begin Scalar Fsign,Fex,Fdigits,K,N,Flist,Ilist; If Flt = FltZero!* then return "0.0"; If Flt < FltZero!* then <<Fsign:='T; Flt:=-Flt>>; Fex:=FindExponent(Flt); Flt:=Flt/FloatPower10(Fex); % Ie, FindMantissa % At this point, % FEX is an integer % and 0.0 =< Flt <1.0 % Now we can move the Point and adjust the Exponent by a scale % factor for "nicety", or to eliminate En If Fex>=MinNice and Fex<=maxNice then <<Flt:=Flt*FloatPower10(Fex); Fex:=0>> else if scale neq 0 then <<Flt:=Flt*FloatPower10(Scale); Fex:=Fex-Scale>>; % Remove and convert the Integer Part (0 if scale=0 and not-nice). Ilist:=Fix(Flt); Flt:=Flt-Float(Ilist); If Fsign then Ilist:=-Ilist; Ilist:=Char('!.) . Reverse Int2List Ilist; % Reverse % Start shifting off digits in fraction by multiplying by 10 % Also Round here. % Should we adjust Ndigits if "nice/scale" ?? Flist:=Ilist; % Add in fraction digits, remember point for trailing % Zero Removal For K:=1:NDigits do << Flt := Flt * FltTen!*; N:=Fix(Flt); Flt:=Flt-FltDigits[N]; Flist := (N + Char '0) . Flist; >>; % Truncate excess trailing 0's While PairP Flist and Not (Cdr Flist eq Ilist) and Car(Flist)=Char '0 do Flist:=cdr Flist; % Now Optimize format, omitting En if 0 If Fex=0 then Return List2String Reverse Flist; % Now convert the Exponent and Insert Fex:=Int2List Fex; Flist := Char('E) . Flist; % The "E" For each x in Fex do Flist:= x . Flist; Return List2String Reverse Flist; end; procedure Int2String N; % Convert signed integer into a string List2String Int2List N; Procedure Int2List N; % Return "exploded" number, forward order Begin scalar L,Nsign; If N=0 then return List Char '0; If N<0 then <<N := -N; Nsign :=T>>; While N>0 do <<L := (Remainder(N,10) + Char '!0 ) . L; N := N / 10>>; If Nsign then L := Char('!-) . L; Return L; End; %Syslsp Procedure WriteFloat(Buffer,Fbase); % Buffer is Wstring[0..40], % Fbase is FloatBase FltInf Flt % Begin Scalar s,flt,i,ss; % flt := MKFLTN (Fbase-4); %/4 or 1 % s:=Flt2String flt; % ss:=strinf(s); % i:=strlen(ss); % strlen(Buffer):=i; % i:=i+1; % while i>=0 do <<strbyt(Buffer,i) := StrByt(ss,i); % i:=i-1>>; % end; End;