
   Operations with  real values in Rigal
  =======================================

NOTE:
This description presents implementation of
operations with  real values in Rigal in 
MS-DOS (Turbo-Pascal based) and UNIX (C - based)
variants, starting from Rigal V.2.34 and UNIX Rigal V.4.45.
Read carefully parts regarding UNIX and MS-DOS. 

 Old such description was for MS-DOS version 
only. Unix description exists only starting from version
4.45.

   Limitations of Turbo Pascal
   ===========================

MS-DOS Rigal is implemented via Pascal real run time library. The
following sequence of characters is accepted by Pascal VAL
procedure as a real number:

  (* space *) [ (+!-) ] (* digits1 *) [ '.' (* digit2 *) ]
              [ (e!E)   [ (+!-) ] (* digit3 *) ]
  The context constraints are that:
   digit1+digit2<37  ( limited number of digits )
   The absolute value of digits1.digits2E[-]digits3 must be
   in 2.9e-39 ... 1.7e38

  We assume that UNIX C has no such constraints.

  Input real number from lexical analyzer
  =======================================

We call real numbers stored in Rigal memory as #FATOMs. Use
built-in Rigal predicate #FATOM to recognize them. They
can be read by the lexical analyzer from its input as
sequences of characters that must match following grammar
rule

   (+ digits1 +)
   ( '.' (* digit2 *)  [ (e!E)   [ (+!-) ] (* digit3 *) ]
   !                     (e!E)   [ (+!-) ] (* digit3 *) )

and it must be acceptable by procedure VAL (see above).

IN MS-DOS:
=========
If #FATOM is read then it is stored in 8-byte-length atom, 6
bytes are occupied by standard representation of REAL type
in Pascal. In other two bytes number of digits before dot
and number of digits after the dot are stored. If the input
number was in exponential form then these bytes contain
zeros.

IN UNIX:
=======
If #FATOM is read then it is stored in 8-byte-length atom,
assuming that sizeof(double)=8. The information about the 
number of digits before the dot and number of digits after
the dot are _NOT_ stored.


Since standard 6 (or 8)-byte representation is stored, only 10 (13)
 digits are valid.

Non-matching in MS-DOS scaner 
=============================
If the input value matches grammar and does not match "VAL
rules"  then atom with type #KEYWORD is produced (it is
used for diagnostic purposes).  Normally #FATOM is produced.

Output of real numbers
======================
 Statements PRINT, <<, ,<], built-in rules #IMPLODE and
#EXPLODE output real numbers in "exponential" form,
like the %E format in UNIX, or simple WRITE() in Pascal.

    Sd.ddddddddddEZdd
  S is space or '-'
  d are digits (exactly 10 digits after dot)
  E is character 'E'
  Z is '+' or '-'

 Real numbers in traditional operators
 =====================================
  If you use real numbers in traditional arithmetical
operators and comparisons, all #FATOMs  are accepted the
same way as NULL. It corresponds to 0 value. If you  compare
#FATOMs with '=', their internal representation (with 6
or 8 bytes long code) will be compared. Therefore, there
is no sense in such operations.

  Ways to create #FATOM
  =====================
 #CALL_PAS(80 S any_string)
  returns #FATOM if the string value matches "VAL rule".
Otherwise NULL is returned.

  #CALL_PAS(80 I integer)
  returns #FATOM. Integer value can be arbitrary.


  Ways to get information from #FATOM
  ===================================
 ( THIS APPLIES TO MS_DOS VARIANT ONLY !)
 ====================================== 
  #CALL_PAS(80 D #FATOM) returns pair
   (. digits_before  digits_after .)
  for FATOM values that were entered through the
lexical analyzer. If the number was entered in exponential
style (with character, 'E'), value (. 0 0 .) is returned.
If the value was obtained by #CALL_PAS(80..),  NULL is
returned. There is no other ways to create #FATOM.

  NOTE:
 If you have entered #FATOM to variable $X via lexical
analyzer, you can output it with the same number of digits
before and after the point (if it was not exponential
style) as it was read by lexical analyser:

  $D:=#CALL_PAS(80 D $X);
  IF $D AND ($D[1]+$D[2]>0) ->
   $REZ:=#CALL_PAS(80 Z $X ($D[1]+$D[2]+1)*100+$D[2])
  ELSIF T->
   $REZ:=#CALL_PAS(80 V $X)
  FI;

  Conversions (MS-DOS VARIANT ONLY)
  =================================
  #CALL_PAS(80 T #FATOM)
  returns #NUMBER - whole part of real value. If the
number is not in -2147483648..2147483647 then NULL is
returned.

  #CALL_PAS(80 Z #FATOM D*100+A)
  returns formatted string with the value of the real
number. "A" can be positive or negative.

  If "A" is arbitrary NEGATIVE number then exponential form
is produced in following form:
   Sd.dEZdd (e.g. -7.7E01)
   S is  space or '-' Z is '-' or '+'

  If D>=9 then additional digits are added after the point,
but not more than 10 digits.

  If "A" is 0 then integer value is produced, possible with
'-'.
  If "A" is positive, it specifies number of digits after
the point. Non-exponential form is produced.
Zeros are appended after point if necessary. The
number of digits after the point cannot be larger than 11.

  After all cases discussed above, if "D" is larger than the
new string, RIGAL adds spaces from the left side of the
string. The result string length is not less than "D".

  #CALL_PAS(80 R #FATOM p)
  - returns rounded value of real number. The number is
rounded such way that digits after p-th position after the
dot  must be set to zeros. E.g. 23.1415 rounded at 2 nd
position must be 23.140000.
   If p is not positive, it is  accepted as 0.  If absolute
value of real*(10 in p-th degree) is larger than 1e37 then
NULL is returned.

  #CALL_PAS(80 V #FATOM)
  - creates string from real number in form
    [-]d.ddddddddddESdd
    S is '+' or '-'

 Conversions (UNIX VARIANT ONLY)
 =================================

 #CALL_PAS(80 F #FATOM  FORMAT_STRING)
  returns   formatted string with UNIX C the _arbitrary_ format
  (allowed in UNIX C sprintf function) you specified, 
  for example   #CALL_PAS(80 F $A  'A=%.9e');
  Note, however, that this option is _not_ ported to MS-DOS.

 #CALL_PAS(80 Z #FATOM D*100+A)
  returns formatted string with the value of the real
number. "A" _must_ be positive.

  If "A" is 0 then integer value is produced, possible with
'-'.
  If "A" is positive, it specifies number of digits after
the point. Non-exponential form is produced.
Zeros are appended after point if necessary. The
number of digits after the point cannot be larger than 11.

  After all cases discussed above, if "D" is larger than the
new string, RIGAL adds spaces from the left side of the
string. The result string length is not less than "D".

 #CALL_PAS(80 V #FATOM)
  returns   formatted string with UNIX C  %E format.

 Mathematical operations
 =======================

  #CALL_PAS(80 op #FATOM #FATOM)
  Operations "op" can be '+','-', '*','/',  '<','>',
'<=','>=', '<>','='
  In MS-DOS  if '+' or '-' applied, absolute value of the arguments
must be less than 6.2e37 otherwise NULL is returned.

   In MS-DOS  if '*' or '-' applied, absolute value of the result must
be between 1.6e-38..6.2e37 and the second argument of '/' is
not 0, otherwise NULL is returned.
  If '<','>','<=','>=','<>','=' are applied, one of the
arguments is returned to indicate 'true', NULL is returned
to indicate 'false' Note that it is BAD and DANGEROUS STYLE to check the
results of real arithmetic using '=' or '<>' operations,
because the computer never calculates precise results. You
can compare two real numbers only after some conversion,
e.g. using #CALL_PAS(80 V ...).

 #CALL_PAS(80 Q #FATOM) returns square root if argument is
not negative, NULL otherwise.

  #CALL_PAS(80 X #FATOM) returns exponential ( e in r-th
degree) of the argument.

  #CALL_PAS(80 L #FATOM) returns natural logarithm if the
argument is positive, otherwise NULL.

  Mathematical operations for UNIX only
  ===================================== 
#CALL_PAS(80 op #FATOM)

 where op = tSIN, tCOS, tTAN, tASIN, tACOS, tATAN.
 
 call corresponding functions from UNIX libm library.



   Common note about #CALL_PAS(80..).
   =================================
  It has no run time diagnostic.
  If wrong types of arguments  of wrong number of arguments
or wrong operation name is given, NULL is returned.
  If #CALL_PAS(80...) produces a #FATOM, it is 6 (or 8) bytes long
and it has _no_ information about the digits before and after
the dot.
  You can learn more details about #CALL_PAS(80) from
source files USE80.PAS and SERVICES.PAS in MS-DOS,
usemod.c, sevice.c in UNIX C.
