home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / misc / math / fastplot / source / stringutils.mod < prev    next >
Encoding:
Modula Implementation  |  1995-03-27  |  4.1 KB  |  227 lines

  1. (*********************************************************************)
  2. (*                                                                   *)
  3. (* Module StringUtils Copyright © 1994 by Computer Inspirations      *)
  4. (*                                                                   *)
  5. (*********************************************************************)
  6.  
  7. IMPLEMENTATION MODULE StringUtils;
  8.  
  9. FROM SYSTEM IMPORT BYTE;
  10.  
  11. CONST
  12.   ZERO  = 0.0;
  13.   ONE   = 1.0;
  14.   TEN   = 10.0;
  15.   TENTH = 0.1;
  16.  
  17.  
  18. PROCEDURE PowerOfTen(power:INTEGER): REAL;    (*10^power*)
  19. VAR
  20.   result : REAL;
  21. BEGIN
  22.   result := 1.0;
  23.  
  24.   IF power > 0 THEN
  25.     REPEAT
  26.       result := result * TEN;
  27.       DEC(power);
  28.     UNTIL power=0;
  29.   ELSIF power < 0 THEN
  30.     REPEAT
  31.       result := result / TEN;
  32.       INC(power);
  33.     UNTIL power=0;
  34.   END;
  35.  
  36.   RETURN result;
  37. END PowerOfTen;
  38.  
  39.  
  40. PROCEDURE GetExp(num:REAL): INTEGER;
  41. VAR
  42.   i : INTEGER;
  43.   b : RECORD
  44.         CASE :CARDINAL OF
  45.           |0: r           : REAL;
  46.           |1: b0,b1,b2,b3 : BYTE;
  47.         END;
  48.       END;
  49. BEGIN
  50.   b.r:=num;
  51.   i := INTEGER(b.b3) MOD 128;
  52.  
  53.   IF i>3FH THEN
  54.     i:= (LONGCARD(i)-3FH)*77 DIV 256;
  55.   ELSE
  56.     i:= -INTEGER((3FH-LONGCARD(i))*77 DIV 256);
  57.   END;
  58.   RETURN i;
  59. END GetExp;
  60.  
  61.  
  62. PROCEDURE ConvRealToStr(VAR str:ARRAY OF CHAR;
  63.                         num:REAL;
  64.                         minchars:CARDINAL;
  65.                         fracchars:INTEGER;
  66.                         pad:CHAR): BOOLEAN;
  67. CONST
  68.   RAcc = 6; (* digits of accuracy in REAL we can count on *)
  69. VAR
  70.   D,s,exp : INTEGER;
  71.   buffer  : ARRAY [0..80] OF CHAR;
  72.   pos,i,j : INTEGER;
  73.   useExp  : BOOLEAN;
  74.  
  75.   PROCEDURE PutCh(c:CHAR);
  76.   BEGIN
  77.     buffer[pos]:=c;
  78.     INC(pos);
  79.   END PutCh;
  80.  
  81.   PROCEDURE PutNumDig(c:CARDINAL);
  82.   BEGIN
  83.     buffer[pos]:=CHR(c+ORD("0"));
  84.     INC(pos);
  85.   END PutNumDig;
  86.  
  87.   PROCEDURE PutExp(exp:INTEGER);
  88.   BEGIN
  89.     PutCh('E');
  90.     IF exp<0 THEN
  91.       PutCh('-');
  92.       exp:=-i;
  93.     END;
  94.  
  95.     IF exp>10 THEN
  96.       PutNumDig((exp MOD 100) DIV 10);
  97.     END;
  98.  
  99.     PutNumDig(exp MOD 10);
  100.   END PutExp;
  101.  
  102. BEGIN
  103.   pos:=0;
  104.  
  105.   D := ABS(fracchars);
  106.   useExp:= (fracchars < 0);
  107.  
  108.   IF num < ZERO THEN
  109.     PutCh("-");
  110.     num := -num;
  111.   END;
  112.  
  113.   IF num=ZERO THEN
  114.     exp := 0;
  115.     num := ZERO;
  116.   ELSE
  117.     (* round to D digits to the right of the decimal *)
  118.     IF D > RAcc THEN
  119.       D := RAcc;
  120.     END;
  121.     num:=num+PowerOfTen(-D)*0.5;
  122.  
  123.     (* normalize number *)
  124.     exp := GetExp(num);
  125.     num := num / PowerOfTen(exp);
  126.  
  127.     (* check if rounding changed first digit of mantissa *)
  128.     (* i.e., 9.99999 changed to 10.00000 *)
  129.     IF num >= TEN THEN
  130.       num := num / TEN;
  131.       INC(exp);
  132.     END;
  133.  
  134.     (* special case when ABS(num) < 1.0 *)
  135.     IF num < 1.0 THEN
  136.       num := num * TEN;
  137.       DEC(exp);
  138.     END;
  139.  
  140.     (* check if this number can be represented
  141.        in ordinary form *)
  142.     IF ABS(exp) > RAcc THEN
  143.       useExp := TRUE;
  144.     END;
  145.   END;
  146.  
  147.   IF useExp THEN
  148.     PutNumDig(TRUNC(num));
  149.     PutCh(".");
  150.  
  151.     j:=D;
  152.     WHILE j>0 DO
  153.       num := (num - FLOAT(TRUNC(num))) * TEN;
  154.       PutNumDig(TRUNC(num));
  155.       DEC(j);
  156.     END;
  157.  
  158.     PutExp(exp);
  159.  
  160.   ELSE
  161.     s := exp;  (* begin with digits to left of decimal *)
  162.     IF exp < 0 THEN
  163.       s := 0;  (* begin at zero to left of decimal *)
  164.     END;
  165.  
  166.     i := 0;
  167.     FOR j := s TO (-D) BY -1 DO
  168.       IF (i > RAcc) OR (exp < 0) THEN
  169.       (* use dummy zeros to pad right *)
  170.         PutCh("0");
  171.       ELSE
  172.         PutNumDig(TRUNC(num));
  173.         num := (num - FLOAT(TRUNC(num))) * TEN;
  174.       END;
  175.       INC(i);
  176.       INC(exp);
  177.       IF j = 0 THEN
  178.         PutCh(".");
  179.       END;
  180.     END;
  181.   END;
  182.  
  183.   PutCh(0C);
  184.  
  185.   IF (minchars>HIGH(str)) OR (CARDINAL(pos)>HIGH(str)) THEN
  186.     RETURN FALSE;
  187.   END;
  188.  
  189.   i:=0;                    (* put padding *)
  190.   WHILE i+pos<=INTEGER(minchars) DO
  191.     str[i]:=pad;
  192.     INC(i);
  193.   END;
  194.  
  195.   j:=-1;
  196.   (* copy data into destination *)
  197.   REPEAT
  198.     INC(j);
  199.     str[i]:=buffer[j];
  200.     INC(i);
  201.   UNTIL buffer[j]=0C;
  202.  
  203.   IF (j > 0) & (str[j-1] = '.') THEN
  204.     (* remove trailing '.' *)
  205.     str[j-1] := 0C;
  206.   END;
  207.  
  208.   RETURN TRUE;
  209. END ConvRealToStr;
  210.  
  211.  
  212. PROCEDURE LengthStr(s : ARRAY OF CHAR) : CARDINAL;
  213. VAR
  214.   i : CARDINAL;
  215. BEGIN
  216.   i := 0;
  217.   WHILE (s[i] # 0C) & (i # HIGH(s)) DO
  218.     INC(i);
  219.   END;
  220.   IF s[i] # 0C THEN
  221.     INC(i);
  222.   END;
  223.   RETURN i;
  224. END LengthStr;
  225.  
  226.  
  227. END StringUtils.