Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-03 - decus/20-0078/libsim/putflo.sim
There is 1 other file named putflo.sim in the archive. Click here to see a list.
OPTIONS(/E/C/-Q/-I/-D/-A);
! PROCEDURE PUTFLOAT edits a number X into the text T
! (right justified).
!
! Insignificant trailing zeros in fractions are removed.
!
! Representation errors (of type 98.9999999) are corrected.
! If fixed point format cannot be used (displaying significant
! digits), floating point format is used instead.
! The output will depend on the length of the text T.
! A value in the range [8,16] is recommended.
!
! PUTFLOAT also returns a reference to the text parameter.
;
    TEXT PROCEDURE putfloat(t,x);   TEXT t;   REAL x;
    BEGIN   INTEGER w;

	w:= t.Length;   t:= NOTEXT;

	IF w = 0 THEN ! NOTEXT !; ELSE
	IF x = 0 THEN t.Sub(w,1).Putchar('0') ELSE
	BEGIN   REAL saved;   BOOLEAN negative;   INTEGER d,i,pow,j;

	    negative:= x < 0;   d:= 8;  ! No. of sign. digits;
	    saved:= x;   x:= Abs(x);

	    IF x >= &8 OR x < &-7 THEN
	    realedit:
	    BEGIN   pow:= 0;
		WHILE x >= 10 DO
		BEGIN   x:= x*0.1;   pow:= pow + 1   END;
		WHILE x < 1 DO
		BEGIN   x:= x*10;    pow:= pow - 1   END;
		! Calculate length for exp part;
		j:= IF pow >= 10 THEN 3 ELSE IF pow >= 0 THEN 2 ELSE
		IF pow >= -9 THEN 3 ELSE 4;

		i:= w - j;
		IF i > (IF negative THEN 1 ELSE 0) THEN
		BEGIN   CHARACTER low10;   TEXT temp;
		    putfloat(t.Sub(1,i),x*sign(saved));
		    t.Setpos(1);   IF t.Getchar = '*' THEN GO TO realcase;
		    temp:- blanks(4); temp.putreal(1,0);
		    temp.Setpos(1);  low10:= temp.getchar;
		    t.Setpos(1);
		    WHILE t.Pos <= i DO
		    IF t.Getchar = low10 THEN GO TO realcase;
		    t.Putchar(low10);
		    t.Sub(i+2,j-1).Putint(pow);
		END ELSE
		realcase:
		BEGIN   i:= w - (IF negative THEN 6 ELSE 5);
		    IF i < 0 THEN i:= 0;
		    IF d > i THEN d:= i;
		    t.Putreal(saved,d)
		END putreal case
	    END realedit block ELSE
	    BEGIN   INTEGER pow_d,pow_di,n1,m,di,ix;

		pow:= 1;
		pow_di:= pow_d:= 100 000 000;   ! = 10**d;

		! Scale x to [0.1,1-eps] ;
		WHILE x >= 1.0 DO
		BEGIN   x:= x*0.1;
		    IF pow_di = 1 THEN GO TO realedit;
		    pow_di:= pow_di//10;
		    i:= i - 1
		END;
		WHILE x < 0.1 DO
		BEGIN   x:= x*10;   pow:= pow*10;   i:= i + 1   END;

		di:= d + i;
		IF di < 0 THEN
		BEGIN   d:= -i;   di:= 0  END;

		ix:= x*pow_d;   ! IX now integer with full prec;

		! Fix 9999.... problem;
		j:= Mod(ix,100);
		IF j >= 90 THEN ix:= ix + 100 - j ELSE
		IF j <= 10 THEN ix:= ix - j;

		n1:= ix//pow_di//pow;	! =  Integer Part;

		! Calculate j = no. of chars before dec. point;
		m:= n1;   j:= IF negative THEN 2 ELSE 1;
		WHILE m >= 10 DO
		BEGIN   m:= m//10;   j:= j + 1   END m loop;

		ix:= ix -(n1*pow_di)*pow;
		! ix = fraction ;

		IF ix NE 0 THEN
		! Remove trailing zeros in IX;
		WHILE Mod(ix,10) = 0 DO
		BEGIN   ix:= ix//10;   di:= di-1   END mod loop;

		IF j + (di+1)*Sign(ix) > w THEN GO TO realedit;

		IF negative THEN n1:= -n1;

		IF ix = 0 THEN t.Putint(n1) ELSE
		BEGIN
		    j:= w-di;
		    IF negative AND n1 = 0 THEN
		    t.Sub(j-2,2):= "-0" ELSE
		    t.Sub(1,j-1).Putint(n1);
		    t.Setpos(j);   t.Putchar('.');
		    t.Sub(t.Pos,di).Putint(ix);

		    ! Fill in zeros;
		    WHILE ix > 0 DO
		    BEGIN   ix:= ix//10;   di:= di - 1   END ix loop;
		    t.Setpos(j+1);
		    FOR j:= 1 STEP 1 UNTIL di DO t.Putchar('0');

		END fraction present
	    END w > 0
	END x not = 0;
	putfloat:- t
    END of putfloat;