home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / misc / icalc.lha / ICalc / Docs / AdvancedGuide < prev    next >
Encoding:
Text File  |  1992-08-03  |  22.4 KB  |  718 lines

  1. =============================================================================
  2.  
  3.     icalc - a complex-number expression language
  4.  
  5.     (C) 1991, 1992 Martin W. Scott. All Rights Reserved.
  6.  
  7.     Version 2.1
  8.  
  9. =============================================================================
  10.  
  11.     Advanced Guide
  12.  
  13. =============================================================================
  14.  
  15. This document describes the more advanced features of icalc, including
  16. programming constructs and array manipulation, as well as some information
  17. that was left out of the User Guide for clarity and continuity.
  18.  
  19. The syntax used in icalc is closely related to that of C, with many
  20. exceptions. Information/warnings specifically for people who are
  21. familiar with C will be indicated by lines prefixed with 'C:'.
  22.  
  23. Parentheses and braces will sometimes be used in examples where they
  24. don't strictly need to be, due to operator precedence rules. They are
  25. included for clarity. (NB: A table detailing relative precedences is in
  26. Appendix 1 of the User Guide.)
  27.  
  28.  
  29.  
  30. Numbers
  31. -------
  32. Icalc can read and display numbers in any base from 2 to 36. The most
  33. common bases used are 10 (almost always), 2 (binary) and 16 (hexadecimal).
  34. For bases greater than 10, the letters from A to Z (upper or lower-case)
  35. are used for the 'digits' 11 to 35. If you don't know what a number-base
  36. is, you may skip this section.
  37.  
  38. When you input a number, icalc assumes it is decimal unless indicated
  39. otherwise. To inform icalc that you are entering a binary number, prefix
  40. it with a percent sign '%'. Similarly, to denote a hexadecimal number,
  41. use a '$' prefix. (Note that there should be no space between the prefix
  42. and the number). For any other base, you should precede the number with
  43. its base, a letter 'r' (in lower case) followed by the number itself.
  44.  
  45. To input negative numbers in a base other than 10, use a minus sign '-'
  46. BEFORE the base-specifier.
  47.  
  48. Examples:
  49.     
  50.     255        - (a) decimal representation of number 255
  51.     %11111111    - binary representation of number 255
  52.     $FF        - hexadecimal representation of number 255
  53.     3r100110    - base-3 representation of number 255
  54.     36r73        - base-36 representation of number 255
  55.     -$A        - hexadecimal representation of number -10
  56.  
  57. Sometimes it is convenient to use scientific notation when representing
  58. very large or small numbers. Usually, the letter 'e' denotes that an
  59. exponent is given, as for example in 1e10 (a 1 followed by 10 zeros).
  60. However, for bases >= 15, 'e' is a digit. I am unaware of any standard
  61. convention in such cases, so opted to use the '@' character, which can be
  62. used with any base (you may still use 'e' for any base < 15 though).
  63.  
  64. The exponent should be entered in the SAME BASE AS THE GIVEN NUMBER, and
  65. icalc displays numbers using this convention also (this seems the
  66. logical and consistent way to do things).
  67.  
  68. More Examples:
  69.  
  70.     1e5        - (a) decimal representation of the number 10000
  71.     %101e11        - binary representation of the number 40
  72.               (%101 = 5, %11 = 3, so %101e11 = 5 * 2^3)
  73.     8r7e7        - octal representation of the number 14680064
  74.               (8r7 = 7, so 8r7e7 = 7 * 8^7)
  75.     $1@10        - hexadecimal representation of the number 16^16
  76.  
  77. When icalc displays a number using scientific notation, it always
  78. explicitly shows the sign of its exponent, eg. entering 1e30 would
  79. produce 1e+30.
  80.  
  81. Fractions are input in the usual way as for decimal numbers. Thus
  82.  
  83.     $FF.FF
  84.  
  85. represents the number 15*16 + 15*1 + 15/16 + 15/(16^2), whilst
  86.  
  87.     %101.101
  88.  
  89. represents the number 1*4 + 0*2 + 1*1 + 1/2 + 0/4 + 1/8.
  90.  
  91. Note that to convert from one base to another, it is not enough just to
  92. convert each of the integer fraction and exponent parts separately. But
  93. anyway, you can use icalc for all base conversions you might want.
  94.  
  95. To specify which base icalc should display numbers, use the builtin
  96. outbase(n) - this affects all numbers output, except array indices output
  97. with the display() builtin (see the section on  arrays below).
  98.  
  99. The display routine in icalc prints a number to a certain number of
  100. significant digits. This is 12 by default, but may be changed by the
  101. prec() builtin. Entering prec(n) sets the number of significant digits
  102. to n. n must lie in the range 1 to 55. prec() returns the last answer
  103. (ans) so that you can see the effect immediately. It allows values up to
  104. 55 only for representations in lower bases -- you don't get 55 digits of
  105. precision using decimal representations. To save time, the functions
  106. bin(), oct(), dec() and hex() are defined in the 'icalc.init' file for
  107. your use. They set respectively base 2, 8, 10 and 16, as well as setting
  108. a suitable precision for numbers to be displayed at.
  109.  
  110. Generally speaking, icalc doesn't consider leading zeros in a fraction as
  111. significant, e.g. in the number 0.0012, the significant part is 12. If a
  112. fraction has more than the set number of significant digits, it is
  113. displayed in scientific notation. Whilst this gives the desired number
  114. of significant digits, it is sometimes aesthetically unpleasing.
  115. Therefore, a fixed number of leading zeros are condidered significant,
  116. by default 4. This can be altered by the sigzeros(n) builtin. Note that
  117. if n is zero, numbers will always be displayed with the set number of
  118. significant digits.
  119.  
  120. To demonstrate what I mean, here's an example (assuming default settings):
  121.  
  122.     > PI
  123.         3.14159265359
  124.     > PI/10
  125.         0.31415926536
  126.     > PI/1000
  127.         0.00314159265
  128.     > PI/100000    # gives rise to 5 leading zeros
  129.         3.14159265359e-5
  130.     > sigzeros(5)
  131.         0.00003141593
  132.         ^ ^^^^
  133.         these 5 zeros are considered significant
  134.  
  135.  
  136. And finally, a small example on rounding errors. Recall from the user
  137. guide the example expression
  138.  
  139.     sin(2*x) - 2*sin(x)*cos(x)
  140.  
  141. where x had the value 4, and the expression returned 2.22044604925e-16.
  142. This looks at first like a rather strange error, but turns out not to be.
  143. The following sample session shows why:
  144.  
  145.     > x = 4
  146.         4
  147.     > sin(2*x) - 2*sin(x)*cos(x)
  148.         2.22044604925e-16
  149.     > bin()  # sets prec to 35
  150.         %1e-110100
  151.     > prec(55)  # we can see what's happened, but let's see better
  152.         %0.0000000000000000000000000000000000000000000000000001
  153.  
  154. and we see that the apparently strange error is actually caused by one
  155. bit in the computer's (binary) representation of the result. Not at all
  156. strange...
  157.  
  158.  
  159.  
  160. Principal value ranges (PVRs)
  161. -----------------------------
  162. The PVRs are defined for the inverse trigonometric functions as follows:
  163.  
  164.     asin:   if u + iv = asin(z), then
  165.         -PI/2 <= u <= PI/2  if v >= 0
  166.         -PI/2  < u  < PI/2  if v < 0
  167.  
  168.     acos:   if u + iv = acos(z), then
  169.         0 <= u <= PI    if v >= 0
  170.         0  < u  < PI    if v < 0
  171.  
  172.     atan:   if u + iv = atan(z), then
  173.         -PI/2 < u < PI/2    
  174.  
  175.  
  176.  
  177. Additional assignment operators
  178. -------------------------------
  179. As well as the standard = operator, icalc comes with some others both to
  180. improve readability and efficiency of functions. They are:
  181.  
  182.     a += b        equivalent to   a = a+b
  183.     a -= b        equivalent to   a = a-b
  184.     a *= b        equivalent to   a = a*b
  185.     a /= b        equivalent to   a = a/b
  186.  
  187. It is faster to use these operators rather than the explicit operations.
  188.  
  189. C: The ++ and -- operators are not included, since the evaluation method
  190. C: cannot handle pre- and post- operations rigorously.
  191.  
  192.  
  193.  
  194. Relational operators
  195. --------------------
  196. These operators allow comparisons between two values. Of course, the set of
  197. complex numbers has no logical ordering; all relational comparisons are
  198. done with real parts only, but equivalence comparisons are done on both
  199. real and imaginary parts. This system allows for people who are writing
  200. real-number applications to once again completely ignore complex numbers. 
  201. To use relational operators on imaginary parts, you must use Im().
  202.  
  203. Relational operators are used in BOOLEAN expressions; these expressions can
  204. take one of two values: TRUE (1.0) and FALSE (0.0). In the table below, a and
  205. b represent numerical expressions, and E and F represent boolean expressions.
  206.  
  207.  
  208.     BOOLEAN EXPRESSION    TRUE if and only if
  209.  
  210.     a == b            a has same value as b 
  211.     a != b            a has different value to b
  212.     a > b            value of a greater than that of b
  213.     a >= b            value of a greater than or equal to that of b
  214.     a < b            value of a less than that of b
  215.     a <= b            value of a less than or equal to that of b
  216.  
  217.     E && F            E is TRUE and F is TRUE
  218.     E || F            E is TRUE or F is TRUE
  219.  
  220. Examples:
  221.  
  222.     5 > 3            TRUE
  223.     2 != 2            FALSE
  224.     2 + 10i >= 20 + i    FALSE  (imaginary parts are ignored)
  225.     3 > 2i            TRUE   (2i has real part 0.0)
  226.     -3 > 2i            FALSE
  227.  
  228. and as always, consider rounding errors when comparing:
  229.  
  230.     PI == atan(1)*4        FALSE
  231.  
  232.  
  233. The logical operators && and || use short-circuit evaluation. This means
  234. that they only evaluate their right-hand argument if the result of the
  235. operation is still undetermined. An example will clarify.
  236.  
  237.     (5 > 3) && (6 < 8)  Needs to evaluate E and F
  238.        E          F
  239.  
  240.     (5 > 8) && (6 < 8)  E evaluates to FALSE, so expression is false,
  241.        E          F     and so F is not evaluated.
  242.  
  243. This has some important implications, for example if (boolean) expression F
  244. contained an assignment expression, then it might not be evaluated
  245. depending on expression E.
  246.  
  247. I have found that short-circuit evaluation is the most convenient way of
  248. handling && and ||. Some languages don't guarantee even order of evaluation
  249. (e.g. Pascal) and this can sometimes create harder to read programs.
  250.  
  251. One other operator is present in icalc, as a shorthand for if-then-else
  252. statements, the ternary operator, '?:'. This has the form
  253.  
  254.     E ? a : b
  255.  
  256. and reads as "if E is true then the value of the ternary operator is a,
  257. otherwise it's b". Only one of a or b is evaluated. An example will clarify:
  258.  
  259.     (x >= 2) ? (x -= 1) : (x = 100)
  260.  
  261. means "If x is greater than 2, then subtract one from x, otherwise assign the
  262. value 100 to x".
  263.  
  264. Numerical expressions can stand in for boolean expressions. A numerical
  265. expression has boolean value TRUE if its real part is non-zero, and FALSE
  266. if it is zero.  So, for example, if x is purely real,
  267.  
  268.     y = (x ? 1 : 0)            (*)
  269.  
  270. is equivalent to
  271.  
  272.     y = (x != 0 ? 1 : 0)        (**)
  273.  
  274. and assigns 1 to y if x is non-zero, and 0 to y if x is zero.
  275.  
  276. Do remember that imaginary parts are ignored in comparisons. In x were
  277. purely imaginary, (*) and (**) would assign 1 and 0 respectively to y (i.e.
  278. they would behave differently).
  279.  
  280.  
  281.  
  282. Arrays 
  283. ------
  284. icalc has simple one-dimensional arrays, which can only be declared outside
  285. function definitions. Array elements are referenced using square brackets,
  286. and the first element by default has index 1, but this can be changed.
  287.  
  288. C: This is in contrast to C, where indices start at zero. The system used in
  289. C: icalc is more suited to many mathematical applications.
  290.  
  291. To create an array a, use the statement
  292.  
  293.     array a[dimension]  # creates cleared array
  294.  
  295. The dimension should be a positive integer. It may be an expression, which
  296. will have its imaginary part discarded, and rounded DOWN to an integer.
  297. All elements initially hold the value zero.  You may optionally pre-assign
  298. the array at creation by using
  299.  
  300.     array a[dimension] = { expr1, expr2, ... exprP }
  301.  
  302. This second form allows pre-initialization of elements 1 to P;
  303. P must be <= dimension (so can partially initialise array).
  304.  
  305. Arrays are referenced by a[expr], the index being calculated as the
  306. real part of <expr> rounded to the NEAREST integer.
  307. NB: in version 2.0, the index was calculated as the floor of the real
  308. NB: value.
  309.  
  310. Range checking is performed, and user will be informed of invalid array
  311. references. 
  312.  
  313. As already mentioned, arrays must be created at the top level, ie. NOT in
  314. function definitions.  In this version, there are NO local (to function)
  315. arrays.
  316.  
  317. There are a few builtin functions to help you manuipulate arrays:
  318.  
  319.     arraybase(n)    index n now denotes 1st element of all arrays
  320.     sizeof(a)    returns number of elements in a,
  321.     resize(a,n)    resizes a to n elements,
  322.     display(a)    prints a list of elements in a.
  323.  
  324. The latter two functions return a value 1 by convention. If you resize()
  325. an array to make it larger, the new elements created will NOT be set to
  326. zero.
  327.  
  328. The arraybase routine lets you change how arrays are indexed. As already
  329. stated, the first element by default has index 1. Using arraybase, any
  330. non-negative integer may be used (primarily zero, as in C). arraybase(n)
  331. returns the old base, so you can write functions which set things up how
  332. the like at the start, and restore them when they return. Also, the
  333. constant ABASE holds the current setting, so functions can also use that
  334. to handle whatever preference is set. arraybase returns the value -1 if
  335. given an invalid argument.
  336.  
  337. In the example scripts contained in the distribution of icalc, I have
  338. NOT provided for array bases other than 1, except in zroots.ic, where
  339. the routines change and restore the arraybase to suit their needs. If
  340. you wish to use the other routines with a different base, you will have
  341. to modify them using one of the above methods (I didn't want to confuse
  342. the examples with excess baggage).
  343.  
  344. Here is a small example session to demonstrate some features:
  345.  
  346.     > array a[3] = { 1, 2, 3 }
  347.     > display(a)
  348.         a[1] =  1
  349.         a[2] =  2
  350.         a[3] =  3
  351.         1
  352.     > a[2] = 12
  353.         12
  354.     > a[3] < a[2] ? x = 3 : x = 2
  355.         3
  356.     > sizeof(a)
  357.             3
  358.     > resize(a,4)      # a[4] will contain garbage
  359.         1
  360.     > a[4] = 4
  361.         4
  362.     > display(a)
  363.         a[1] =  1 
  364.         a[2] =  12
  365.         a[3] =  3 
  366.         a[4] =  4 
  367.         1        
  368.     > resize(a,2)
  369.         1
  370.     > display(a)
  371.         a[1] =  1 
  372.         a[2] =  12
  373.  
  374.  
  375.  
  376. Blocks
  377. ------
  378. Blocks are a way to group expressions so they are treated as one big
  379. expression. They have the form
  380.  
  381.     { expr1; expr2; ... exprN; }
  382.  
  383. and the value of a block is the value of its last expression, exprN.  The
  384. expressions may also be separated by newlines (as many as you like)instead.
  385. Blocks can have as little as one expression, which is sometimes useful for
  386. easier-to-read source code.
  387. Examples:
  388.  
  389.     > { a=3;b=2;a*b;}
  390.         6
  391.     > {
  392.     >  a = 2
  393.     >  b = 3
  394.     >  c = 4; d = 5
  395.     >  a*b*c*d
  396.     > }
  397.         120
  398.  
  399. Blocks are principally of use with control-flow constructs, and further
  400. (more useful) examples are given below.
  401.  
  402.  
  403.  
  404. Control-flow constructs
  405. -----------------------
  406. A number of control-flow constructs are available, closely modelled on those
  407. of the C language.
  408.  
  409. C: C is a free-form language, and spacing can appear anywhere in C source.
  410. C: icalc however, is free-form only per-line, due to its interactive nature;
  411. C: icalc must be able to determine when an expression stops, so that it knows
  412. C: when to print a result. Care should be taken to follow icalc's conventions.
  413.  
  414. Where newlines are shown, they are optional; where they are not shown, they
  415. are not permitted, and will either cause a syntax error, or incorrect
  416. behaviour. All horizontal spacing is optional, and used for clarity.
  417.  
  418. Below, Bexpr denotes a boolean expression, Texpr is the expression
  419. evaluated if Bexpr is TRUE, and Fexpr the expression evaluated if Bexpr is
  420. FALSE.
  421.  
  422. if-else
  423. -------
  424. A construct common to almost all programming languages is the if-statement.
  425. In icalc, it has the form
  426.  
  427.     if (Bexpr)
  428.         Texpr
  429.  
  430. or with an else-clause,
  431.  
  432.     if (Bexpr) 
  433.         Texpr else
  434.             Fexpr 
  435.  
  436. Note that 'else' keyword must be on same line as Texpr. If it were allowed
  437. on the next line, non-else-clause if-statements would cause problems in
  438. interactive use. It sometimes looks ungainly, but blocks may be used to
  439. spread it over lines, as shown below.
  440. Some examples:
  441.  
  442.     if (a == 2)
  443.         b = a+1
  444.  
  445.     if (a == 2)
  446.         b = a+1 else b = a-1
  447.  
  448.     if (a == 2) {
  449.         b = a+1
  450.     } else {
  451.         b = a-1
  452.     }
  453.  
  454. while-loop
  455. ----------
  456. This is an iteration construct, of the form
  457.  
  458.     while (Bexpr)
  459.         Texpr
  460.  
  461. and reads as "while the boolean expression Bexpr evaluates to TRUE, evaluate
  462. Texpr".  The following example calculates n!, where n is an integer:
  463.  
  464.     f = 1; n = 10;      # initialize f, n
  465.     while (n > 0)       # n not yet zero, so still work to do
  466.     {
  467.         f *= n      # multiply f by n
  468.         n -= 1      # decrement n
  469.     } 
  470.     # f now holds value of 10!
  471.  
  472. do-while-loop
  473. -------------
  474. This is another iteration construct, closely related to a while-loop, with
  475. the distinction that the loop-test (the boolean expression governing the
  476. loop's operation) is performed AFTER the body of the loop. It has the form
  477.  
  478.     do 
  479.         Texpr
  480.     while (Bexpr)
  481.  
  482. Texpr is evaluated first; then, if Bexpr is TRUE, Texpr is re-evaluated and
  483. Bexpr tested again; and so on...
  484.  
  485. Whereas with a while-loop, the Texpr may never be evaluated (if Bexpr
  486. evaluates to FALSE initially), in a do-while-loop, Texpr is always
  487. evaluated at least once.
  488. An example -- sin() applied five times to a value x:
  489.  
  490.     n = 5; s = x        # n is number of times to apply sin()
  491.     do {
  492.         s = sin(s)  # apply sin()
  493.         n -= 1      # decrement n
  494.     } while (n >= 1)    # more to do?
  495.  
  496.     # s has value sin(sin(sin(sin(sin(x)))))    (sin 5 times)
  497.  
  498. for-loop
  499. --------
  500. The for-loop in icalc is like that of the C language, and has the form
  501.  
  502.     for (initexpr; condexpr; incexpr)
  503.         expr
  504.  
  505. initexpr, condexpr and incexpr are all optional (but semi-colons ; are not).
  506. The for loop is a shorthand for
  507.  
  508.     initexpr
  509.     while (condexpr)
  510.     {
  511.         expr
  512.         incexpr
  513.     }
  514.  
  515. Example:
  516.     array a[100]
  517.     for (n = sizeof(a); n > 0; n -= 1)
  518.         a[n] = 1
  519.  
  520.     # all elements of a are 1.
  521.  
  522. C: icalc's for-loop is not as flexible as C's; there is no comma operator,
  523. C: and initexpr, condexpr and incexpr can only be simple (not blocks).
  524.  
  525.  
  526.  
  527. Function definitions
  528. --------------------
  529. The User Guide explains how to define simple functions. As mentioned there,
  530. you can use a block as the body of a function (e.g. rec2pol definition).  
  531. There are more sophisticated facilities available, which provide a similar
  532. functionality to that of C. However, for a number of reasons, the syntax
  533. used in icalc differs widely from C's.
  534.  
  535. Function parameters may be one of four types:
  536.  
  537.     VALUE:        These are the normal parameters that we've been using
  538.             all along.
  539.  
  540.     POINTER:    These are like variable parameters in Pascal.
  541.             Denoted in parameter list by *.
  542.  
  543.     ARRAY:        These are passed by reference, NOT value, as in C
  544.             Denoted by @.
  545.  
  546.     EXPR:        Strange one this. It's like a pointer to a function,
  547.             but more/less flexible depending on how you look
  548.             at it. Example below will clarify.
  549.             Denoted by ~.
  550.  
  551. Note that, although a function cannot have local arrays, the array
  552. reference parameter IS local, and completely independent of arrays defined
  553. globally.
  554.  
  555. Functions may also have local variables, introduced by a statement
  556.  
  557.     local v1,v2,v3,...,vN
  558.  
  559. within the function body.  There can be as many local declarations as you
  560. like. All local variables behave like VALUE variables - there are no local
  561. pointers or arrays as yet.
  562.  
  563. C: local declarations apply to the function they appear in; there are no
  564. C: block-local variables.
  565.  
  566. The following small suite of functions demostrate the ideas above.
  567.  
  568.     # swaps values in variables a and b.
  569.     func swap(*a,*b) = {    # a and b are pointers
  570.         local tmp    # only expressions in swap() know about tmp
  571.  
  572.         tmp = a
  573.         a = b
  574.         b = tmp
  575.     }
  576.  
  577.     x = 5; y = 7
  578.     swap(x,y)    # x now holds 7, y holds 5
  579.  
  580.  
  581.     # nexpr is an expression in (global) variable n
  582.     # a is an (arbitrary) array.
  583.     # fill evaluates Nexpr for every index n of array a, and places
  584.     # result in a[n].
  585.     func fill(@a, ~nexpr) = {
  586.         for (n = sizeof(a); n > 0; n -= 1)
  587.             a[n] = nexpr;    # just referencing nexpr causes
  588.                     # it to be evaluated.
  589.     }
  590.  
  591. The return value of a function is the value of the last expression evaluated.
  592. Sometimes it's inconvenient for this to be the case, so the return statement
  593. is provided. A line of the form
  594.  
  595.     return a
  596.  
  597. encountered anywhere during function evaluation will end the function call,
  598. returning the value of a.
  599.  
  600. I'm sure you will agree that these mechanisms allow many sophisticated
  601. operations to be performed by user-functions. The examples in this document
  602. are simple-minded for the most part, to give you the bare facts about what
  603. can be done. I have included many sample script-files containing one or more
  604. function definitions which are useful to a varying degree, and in some
  605. cases add very powerful extensions to icalc.
  606.  
  607.  
  608.  
  609. Script files
  610. ------------
  611. The script files include:
  612.  
  613.     array.ic    - utility routines for arrays
  614.     arraytest.ic    - tests routines defined in array.ic
  615.     bern.ic        - computes Bernoulli numbers
  616.     cheby.ic    - computes coefficients for Chebychev polynomials
  617.     gamma.ic    - gamma and related functions
  618.     gl.ic        - integration by 10-pt Gauss-Legendre quadrature
  619.     loop.ic        - demonstrates all looping constructs
  620.     poly.ic        - polynomial support routines
  621.     root.ic        - root-finding of functions
  622.     sort.ic        - routine to perform Shell sort on arrays
  623.     trig.ic        - some rarely used trig-functions
  624.     zroots.ic    - find all roots of a polynomial (real & complex)
  625.  
  626.     polint.ic     -
  627.     trapzd.ic      |
  628.     qtrap.ic       |- numerical integration routines
  629.     qsimp.ic       |      (see Integration.notes in Scripts directory).
  630.     qromb.ic      -
  631.  
  632.  
  633.  
  634. Undocumented commands
  635. ---------------------
  636. There is a 'clear' command, which deletes from memory a variable, array or
  637. function. However, care MUST be taken, since icalc does not check that the
  638. object being deleted is not referenced elsewhere (in a function). If it is
  639. referenced after it has been deleted, the system will more than likely
  640. crash. The command was only really added to delete large arrays which take
  641. up a lot of memory. You have been warned...  
  642.  
  643.     clear <symbol>
  644.  
  645.  
  646.  
  647. Caveats
  648. -------
  649. Assignment
  650. ----------
  651. When assigning variables within another expression, it is safer to
  652. enclose the assignment in parentheses, to ensure that the expression
  653. is evaluated correctly.
  654.  
  655. Defining functions in terms of other functions
  656. ----------------------------------------------
  657. A function is stored internally as a structure, and a reference to
  658. a function, f, from another, g, creates a pointer to the structure
  659. for f. Thus, changing f changes g also.
  660. An example will illuminate this:
  661.  
  662.     > func f(x) = x*x
  663.     > func g(x) = f(2*x)
  664.     > f(4)
  665.         16
  666.     > g(4)
  667.         64
  668.     > func f(x) = sqrt(x)      # changes behaviour of g
  669.     > f(4)
  670.         2
  671.     > g(4)
  672.         2.82842712
  673.  
  674. Therefore, you cannot use function definitions as a kind of function
  675. assignment.
  676.  
  677. Comparisons
  678. -----------
  679. Due to the inexactness of computer calculations, you must be careful
  680. when using comparison operators. Again, an example will illuminate:
  681.  
  682.     > j = 12*PI
  683.         37.69911184
  684.     > while j != 0 do {print(j); j = j-PI;}
  685.         37.69911184
  686.         34.55751919
  687.             :
  688.         3.14159265
  689.         -3.5527136e-15    <--- not quite zero
  690.         -3.14159265
  691.             :
  692.     etc.
  693.  
  694. The arrow points to the position where, because of rounding errors,
  695. j is not exactly zero, and the loop never terminates, since the
  696. condition j != 0 is always satisfied.
  697.  
  698. There are two ways to get round problems like this. You can use a >=
  699. operator, or, if comparison is with (theoretically) integral values,
  700. the int() function, which rounds its argument to the NEAREST integer.
  701.  
  702.  
  703.  
  704. Questions
  705. ---------
  706. I've tried to cover everything in a clear and precise way, but almost
  707. certainly have failed in some areas. If you have any questions about icalc,
  708. write to me and I'll respond as soon as I can. Addresses are in the User
  709. Guide.
  710.  
  711. Also, if you write any scripts which you feel other users may find useful
  712. (for example, routines applying to physics or astronomy calculations)
  713. please send them to me for inclusion with the next release of icalc.
  714.  
  715. Enjoy,
  716.  
  717.     Martin Scott.
  718.