home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol134 / paszcode.rn$ < prev    next >
Encoding:
Text File  |  1984-04-29  |  9.3 KB  |  278 lines

  1. PROCEDURE rnsetup;                                              {$e-r-}
  2.  
  3. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  4. {* To be executed once, at the start of a run, to set up tables      *}
  5. {* for subsequent use by the RN$ function.                           *}
  6. {*                                                                   *}
  7. {* Requires the following global definitions:                        *}
  8. {*    CONST:  rnleft, rnmax                                          *}
  9. {*    TYP:    rndex, rnpair                                          *}
  10. {*    VAR:    rnset, rnlimit, rnmin                                  *}
  11. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  12.  
  13. VAR
  14.     i : rndex;
  15.     v : rnpair;
  16.  
  17. BEGIN {rnsetup procedure}
  18.     v[1] := 1.0;
  19.     v[2] := 5.0;
  20.     FOR i := rnleft DOWNTO 1 DO
  21.       BEGIN {for}
  22.         rnset[i] := v;
  23.         v[1] := v[1] * 10.0;
  24.         v[2] := v[2] * 10.0
  25.       END;  {for}
  26.     rnlimit := v[1];
  27.  
  28.     v[1] := 0.1;
  29.     v[2] := 0.5;
  30.     FOR i := (rnleft+1) TO rnmax DO
  31.       BEGIN {for}
  32.         rnset[i] := v;
  33.         v[1] := v[1] / 10.0;
  34.         v[2] := v[2] / 10.0
  35.       END;  {for}
  36.     rnmin := v[2]
  37. END;  {rnsetup procedure} {$L+}
  38. FUNCTION strtoreal (given: longstr): real;                      {$e-r-}
  39.  
  40.     {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  41.     {* Given a string containing an alleged real number in external  *}
  42.     {* decimal form, return its value as a real, with grerror=false. *}
  43.     {* If the given value is not valid, return 0.0, grerror=true.    *}
  44.     {*                                                               *}
  45.     {* Validity criteria:                                            *}
  46.     {*                                                               *}
  47.     {*    1.  First non-blank may be a hyphen (for negative number). *}
  48.     {*                                                               *}
  49.     {*    2.  Beginning with first non-blank (or character after     *}
  50.     {*        leading hyphen, if any), each character must be a      *}
  51.     {*        numeral, a comma, or a period.                         *}
  52.     {*                                                               *}
  53.     {*    3.  Only numerals are permitted to the right of the        *}
  54.     {*        (first) period.                                        *}
  55.     {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  56.  
  57. CONST
  58.     comma    = ',';
  59.     decimal  = '.';
  60.     hyphen   = '-';
  61.     blank1   = ' ';
  62. VAR
  63.     i, j     : 1..longlength;
  64.     addend   : real;
  65.     pastdec  : boolean;
  66.     negsign  : boolean;
  67.     result   : real;
  68.     units    : real;
  69. {$L+}
  70. BEGIN {strtoreal function}
  71.     result  := 0;
  72.     pastdec := FALSE;
  73.     grerror := FALSE;
  74.     j := 1;
  75.     WHILE given[j]=blank1 DO
  76.       j := j + 1;
  77.     IF given[j]=hyphen
  78.       THEN
  79.         BEGIN {then}
  80.           negsign := TRUE;
  81.           j := j + 1
  82.         END   {then}
  83.       ELSE negsign := false;
  84.     FOR i := j TO length(given) DO
  85.         IF given[i] IN ['0'..'9']
  86.           THEN
  87.             BEGIN {then}
  88.               addend := ORD(given[i]) - ORD('0');
  89.               IF pastdec
  90.                 THEN
  91.                   BEGIN {then}
  92.                     result := result + (addend*units);
  93.                     units  := units / 10.0
  94.                   END   {then}
  95.                 ELSE result := (result * 10.0) + addend
  96.             END   {then}
  97.         ELSE
  98.           IF ((given[i]=decimal) AND (NOT pastdec))
  99.             THEN
  100.               BEGIN {then}
  101.                 pastdec := TRUE;
  102.                 units   := 0.1
  103.               END   {then}
  104.         ELSE
  105.           IF ((given[i]<>comma) OR (pastdec))
  106.             THEN grerror := TRUE;
  107.     IF grerror
  108.       THEN strtoreal := 0.0
  109.       ELSE
  110.         IF negsign
  111.           THEN strtoreal := -result
  112.           ELSE strtoreal := result
  113. END;  {strtoreal function} {$L+}
  114. FUNCTION rn$ (given: REAL;  retntype: rn$ind): rnstr;  {$C-R+}
  115.  
  116. {** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **}
  117. {* Given a real number, return a "display" representation of that   *}
  118. {* number, punctuated with commas, decimal point and (if number is  *}
  119. {* negative) leading hyphen.  Leading zeroes are suppressed.        *}
  120. {* Precision is specified by global constants RNLEFT and RNRIGHT.   *}
  121. {* If the second parameter = 'FULL', the returned field will be     *}
  122. {* fixed-length (RNLEN), with leading blanks as required;  if       *}
  123. {* "COMPACT", leading blanks will be removed, and the field may be  *}
  124. {* shorter.                                                         *}
  125. {*                                                                  *}
  126. {* If the given number's absolute value is too large to be respre-  *}
  127. {* sented with rnleft positions to the left of the decimal point,   *}
  128. {* a value of all nines (punctuated, and with leading hyphen if     *}
  129. {* appropriate) is returned.                                        *}
  130. {*                                                                  *}
  131. {* External definitions required:                                   *}
  132. {*   CONST     RNLEFT, RNRIGHT, RNMAX - define precision            *}
  133. {*             RNLEN    - length of maximum-size string field       *}
  134. {*   TYPE      RN$IND   - (full, compact)                           *}
  135. {*             RNSTR    - STRING                                    *}
  136. {*             RNDEX    - 0..RNMAX                                  *}
  137. {*             RNLENDX  -                                           *}
  138. {*   VAR       RNSET    - array initialized by RNSETUP              *}
  139. {*   PROCEDURE SETLENGTH - Pascal/Z string procedure                *}
  140. {*********************************************************************}
  141. {**                         COPYRIGHT NOTICE                        **}
  142. {**    Copyright (C) 1981, 1982 by Systems Engineering Associates   **}
  143. {**                    124 West Blithedale Avenue                   **}
  144. {**                 Mill Valley, California  U.S.A.                 **}
  145. {**                                                                 **}
  146. {**  Permission is hereby given to all parties to copy or to adapt  **}
  147. {**   this Function, provided that the full text of this Copyright  **}
  148. {**       Notice is included in each such copy or adaptation.       **}
  149. {*********************************************************************}
  150.  
  151. CONST
  152.     hyphen = '-';
  153.     comma   = ',';
  154.     decimal = '.';
  155.     space   = ' ';
  156.     zero    = '0';
  157.     five    = '5';
  158.     nine    = '9';
  159. VAR
  160.     i        : rndex;
  161.     work     : REAL;
  162.     numeral  : CHAR;
  163.     startsig : rnlendx;
  164.     ptr      : rnlendx;
  165.     shortrn$ : rnstr;
  166.     result   : rnstr;
  167. {$L+}
  168. PROCEDURE rn$mask (xleft, xright : rndex);  {$C-R-}
  169.  
  170. VAR
  171.     i        : rnlendx;
  172.  
  173. BEGIN {rn$mask procedure}
  174.     result := space;
  175.     FOR i := 1 TO xleft DO
  176.       BEGIN {for}
  177.         append(result,space);
  178.         IF ((((xleft-i) MOD 3)=0) AND (i<xleft))
  179.           THEN append(result,comma)
  180.       END;  {for}
  181.     append(result,decimal);
  182.     FOR i := 1 TO xright DO
  183.       append(result,space)
  184. END;  {rn$mask procedure}
  185.  
  186.  
  187. { - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
  188.  
  189.  
  190. PROCEDURE rn$nines;
  191.  
  192. BEGIN {rn$nines procedure}
  193.     startsig := ptr;
  194.     WHILE ptr<rnlen DO
  195.       BEGIN {while}
  196.         IF result[ptr]=space
  197.           THEN result[ptr] := nine;
  198.         IF ptr<rnlen
  199.           THEN ptr := ptr+1
  200.       END   {while}
  201. END;  {rn$nines procedure} {$L+}
  202. PROCEDURE rn$trans;
  203.  
  204. VAR
  205.     i     : rndex;
  206.     basis : 0..255;
  207.  
  208. BEGIN {rn$trans procedure}
  209.     FOR i := 1 TO rnmax DO
  210.       BEGIN {for}
  211.         WHILE result[ptr]<>space DO
  212.           BEGIN {while}
  213.             IF startsig=0
  214.               THEN
  215.                 CASE result[ptr] OF
  216.                     comma  :  result[ptr] := space;
  217.                     decimal:  BEGIN {decimal}
  218.                                 startsig := ptr-1;
  219.                                 result[startsig] := zero
  220.                               END   {decimal}
  221.                   END; {case}
  222.             ptr := ptr + 1
  223.           END;  {while}
  224.         IF work<rnset[i,1]
  225.           THEN
  226.             IF startsig>0
  227.               THEN result[ptr] := zero
  228.               ELSE {no action}
  229.           ELSE
  230.             BEGIN
  231.               IF startsig=0
  232.                  THEN startsig := ptr;
  233.               IF work<rnset[i,2]
  234.                 THEN basis := ORD(zero)
  235.                 ELSE
  236.                   BEGIN
  237.                     work  := work - rnset[i,2];
  238.                     basis := ORD(five)
  239.                   END;  {else}
  240.               WHILE work>=rnset[i,1] DO
  241.                 BEGIN {while}
  242.                   work := work - rnset[i,1];
  243.                   basis := basis + 1
  244.                 END;  {while}
  245.               result[ptr] := CHR(basis)
  246.             END; {else}
  247.         IF ptr<rnlen
  248.           THEN ptr := ptr+1
  249.       END   {for}
  250. END;  {rn$trans procedure} {$L+}
  251. BEGIN {rn$ function} {$C-R+}
  252.     rn$mask(rnleft,rnright);
  253.     IF given<0.0
  254.       THEN work := -given + rnmin
  255.       ELSE work :=  given + rnmin;
  256.     startsig := 0;
  257.     ptr      := 2;
  258.  
  259.     IF work<rnlimit
  260.       THEN rn$trans
  261.       ELSE rn$nines;
  262.     IF given<0.0
  263.       THEN
  264.         BEGIN {then}
  265.           startsig := startsig - 1;
  266.           result[startsig] := hyphen
  267.         END;  {then}
  268.     IF retntype=full
  269.       THEN rn$ := result
  270.       ELSE
  271.         BEGIN
  272.           setlength(shortrn$,0);
  273.           FOR ptr := startsig TO rnlen DO
  274.             append(shortrn$,result[ptr]);
  275.           rn$ := shortrn$
  276.         END   {else}
  277. END;  {rn$ function} {$L+}
  278.