DEFINITION MODULE RealInOut;

(*      Real input output as per Wirth with extensions

        All items (except Done) exists in normal and long versions.*)

  VAR Done : BOOLEAN; 
       (* TRUE if ReadReal or StringToReal returns correct number *)
       
  (* The two first PORCEDUREs don't normaly belong to RealInOut.
     They provide means to overcome two serious problems using
     the TYPE LONGREAL in this Modula-2, and are placed in this
     MODULE only because it is most probably imported to all 
     programs using LONGREALs.
     Examples on how to use LONGREALs can be found in REALINOU.MOD,
     LONGMATH.MOD, and TEST.MOD                                         *)

  PROCEDURE Rec(x : LONGREAL) : LONGREAL; 
      (* Returns 1.0/x in full precision. Use this instead of 
         long division if full double precision is needed 
         with this Modula-2 !
         The standard division '/' is only correct to about the 
         10th significant digit, but faster then Rec *)

  PROCEDURE Long(a,b,c,d,e,exp : INTEGER) : LONGREAL;
      (* Returns a LONGREAL composed of the six INTEGER arguments.
         This should help to overcome some of the problems with 
         non-existing CONSTants of LONGREAL type.
         a, b, c, d, and e should all be positive constants with
         four decimal digits.
         A decimal point should be imagined between the 
         two first digits of a. 
         a, b, c, d, and e are concatenated to a long real number.
         exp is the exponent to ten.
         For example
            LONG(1234,5678,9012,3456,7890,-123)
               = 1.2345678901234567890E-123
         StringToLongReal below provides an alternative to Long.
         (LONG)CARDinals can be converted by FLOATD.
         (LONG)INTegers can be converted by System.FLOATd.
         REALs can be converted by System.FLONG or by assignment
           (both with reduced precision)                               *)

  PROCEDURE ReadReal(VAR x : REAL);

  PROCEDURE ReadLongReal(VAR x : LONGREAL);

  PROCEDURE StringToReal
         (VAR Text : ARRAY OF CHAR; VAR x : REAL;     VAR ReadOK : BOOLEAN);
             
  PROCEDURE StringToLongReal
         (VAR Text : ARRAY OF CHAR; VAR x : LONGREAL; VAR ReadOK : BOOLEAN);

    (*      Convert a string to a real number

            Syntax is [+!-][d*][.d*][E[+!-]d*]

            eg      1.0
                    2
                    .3
                    E3
                    3.45E-17

            Termination character is returned in 
            termCH from InOut (since this module is
            effectively an extension of InOut)

            The StringToReal routines allow you to read a real number 
            from a string. 
            *)

  VAR
  
    Engineering     : BOOLEAN (* = FALSE *);
    
    LongEngineering : BOOLEAN (* = FALSE *); 

    (* if true, engineering exponents are used in WriteReal and 
       RealToString. Engineering exponents are always multiples of 3 *)

    SigDigits     : INTEGER (* = 8 *);

    LongSigDigits : INTEGER (* = 16 *);
    
  (* number of significant digits in WriteReal and RealToString *)
  
    ForceExponent     : BOOLEAN (* = TRUE *); 

    LongForceExponent : BOOLEAN (* = TRUE *); 

    (* set to false to not output exponents of zero on floating point
       numbers*)

  PROCEDURE WriteReal(x : REAL; size : INTEGER);

  PROCEDURE WriteLongReal(x : LONGREAL; size : INTEGER);

  PROCEDURE RealToString
                  (VAR Text : ARRAY OF CHAR; x : REAL;     size : INTEGER);

  PROCEDURE LongRealToString
                  (VAR Text : ARRAY OF CHAR; x : LONGREAL; size : INTEGER);

(*          Convert a real number to a string in mantissa + exponent form

            for example, 10 will be output as 1.0E+01  (Long: 1.0E+001).

            If Engineering is true, the number is scaled so that the 
            mantissa is rounded to a multiple of 3 (the number of digits 
            before the dot is increased).

            so, 10 will print as 10.0E+00   (Long: 10.0E+000).

            The layout is as follows:

            The rightmost 4 (Long: 5) columns of the field are reserved 
            for the  exponent. There must then be SigDigits+2 character 
            positions  left in the field (of size). If  insufficient 
            positions  remain, extra columns are used for the number.

            RealToString returns the number as a zero terminated 
            string in Text
*)

  PROCEDURE WriteRealFixed(x : REAL; size, places : INTEGER);

  PROCEDURE WriteLongRealFixed(x : LONGREAL; size, places : INTEGER);

  PROCEDURE RealToStringFixed
          (VAR Text : ARRAY OF CHAR; x : REAL;     size, places : INTEGER);

  PROCEDURE LongRealToStringFixed
          (VAR Text : ARRAY OF CHAR; x : LONGREAL; size, places : INTEGER);

(*          Write a real number in fixed point.
            size is the size of field to use.
            places is the number of places for decimals.

            If the number is too large to fit in the field, 
            floating point format is reverted to.
        
            If the number is too small, it prints as zero.

            RealToStringFixed returns the value in Text, as a zero 
            terminated string.
*)

  PROCEDURE WriteRealOct(x : REAL; n : CARDINAL);

  PROCEDURE WriteLongRealOct(x : LONGREAL; n : CARDINAL);

         (* output real number in octal for debugging purposes *)
        
  PROCEDURE WriteRealHex(x : REAL; n : CARDINAL);

  PROCEDURE WriteLongRealHex(x : LONGREAL; n : CARDINAL);

         (* output real number in hex for debugging purposes *)

END RealInOut. 
