123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- 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.
- #CALL_PAS(80 P #FATOM #FATOM )
- call the UNIX "pow(x,y)" function.
- 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.
|