calc: Arithmetic Tutorial

 
 3.2 Arithmetic Tutorial
 =======================
 
 In this section, we explore the arithmetic and scientific functions
 available in the Calculator.
 
    The standard arithmetic commands are ‘+’, ‘-’, ‘*’, ‘/’, and ‘^’.
 Each normally takes two numbers from the top of the stack and pushes
 back a result.  The ‘n’ and ‘&’ keys perform change-sign and reciprocal
 operations, respectively.
 
      1:  5          1:  0.2        1:  5.         1:  -5.        1:  5.
          .              .              .              .              .
 
          5              &              &              n              n
 
    You can apply a “binary operator” like ‘+’ across any number of stack
 entries by giving it a numeric prefix.  You can also apply it pairwise
 to several stack elements along with the top one if you use a negative
 prefix.
 
      3:  2          1:  9          3:  2          4:  2          3:  12
      2:  3              .          2:  3          3:  3          2:  13
      1:  4                         1:  4          2:  4          1:  14
          .                             .          1:  10             .
                                                       .
 
      2 <RET> 3 <RET> 4     M-3 +           U              10          M-- M-3 +
 
    You can apply a “unary operator” like ‘&’ to the top N stack entries
 with a numeric prefix, too.
 
      3:  2          3:  0.5                3:  0.5
      2:  3          2:  0.333333333333     2:  3.
      1:  4          1:  0.25               1:  4.
          .              .                      .
 
      2 <RET> 3 <RET> 4      M-3 &                  M-2 &
 
    Notice that the results here are left in floating-point form.  We can
 convert them back to integers by pressing ‘F’, the “floor” function.
 This function rounds down to the next lower integer.  There is also ‘R’,
 which rounds to the nearest integer.
 
      7:  2.         7:  2          7:  2
      6:  2.4        6:  2          6:  2
      5:  2.5        5:  2          5:  3
      4:  2.6        4:  2          4:  3
      3:  -2.        3:  -2         3:  -2
      2:  -2.4       2:  -3         2:  -2
      1:  -2.6       1:  -3         1:  -3
          .              .              .
 
                        M-7 F        U M-7 R
 
    Since dividing-and-flooring (i.e., “integer quotient”) is such a
 common operation, Calc provides a special command for that purpose, the
 backslash ‘\’.  Another common arithmetic operator is ‘%’, which
 computes the remainder that would arise from a ‘\’ operation, i.e., the
 “modulo” of two numbers.  For example,
 
      2:  1234       1:  12         2:  1234       1:  34
      1:  100            .          1:  100            .
          .                             .
 
      1234 <RET> 100       \              U              %
 
    These commands actually work for any real numbers, not just integers.
 
      2:  3.1415     1:  3          2:  3.1415     1:  0.1415
      1:  1              .          1:  1              .
          .                             .
 
      3.1415 <RET> 1       \              U              %
 
    (•) *Exercise 1.*  The ‘\’ command would appear to be a frill, since
 you could always do the same thing with ‘/ F’.  Think of a situation
 where this is not true—‘/ F’ would be inadequate.  Now think of a way
 you could get around the problem if Calc didn’t provide a ‘\’ command.
 See1 Arithmetic Answer 1.  (•)
 
    We’ve already seen the ‘Q’ (square root) and ‘S’ (sine) commands.
 Other commands along those lines are ‘C’ (cosine), ‘T’ (tangent), ‘E’
 (‘e^x’) and ‘L’ (natural logarithm).  These can be modified by the ‘I’
 (inverse) and ‘H’ (hyperbolic) prefix keys.
 
    Let’s compute the sine and cosine of an angle, and verify the
 identity ‘sin(x)^2 + cos(x)^2 = 1’.  We’ll arbitrarily pick -64 degrees
 as a good value for ‘x’.  With the angular mode set to degrees (type
 ‘m d’), do:
 
      2:  -64        2:  -64        2:  -0.89879   2:  -0.89879   1:  1.
      1:  -64        1:  -0.89879   1:  -64        1:  0.43837        .
          .              .              .              .
 
       64 n <RET> <RET>      S              <TAB>            C              f h
 
 (For brevity, we’re showing only five digits of the results here.  You
 can of course do these calculations to any precision you like.)
 
    Remember, ‘f h’ is the ‘calc-hypot’, or square-root of sum of
 squares, command.
 
    Another identity is ‘tan(x) = sin(x) / cos(x)’.
 
      2:  -0.89879   1:  -2.0503    1:  -64.
      1:  0.43837        .              .
          .
 
          U              /              I T
 
    A physical interpretation of this calculation is that if you move
 ‘0.89879’ units downward and ‘0.43837’ units to the right, your
 direction of motion is -64 degrees from horizontal.  Suppose we move in
 the opposite direction, up and to the left:
 
      2:  -0.89879   2:  0.89879    1:  -2.0503    1:  -64.
      1:  0.43837    1:  -0.43837       .              .
          .              .
 
          U U            M-2 n          /              I T
 
 How can the angle be the same?  The answer is that the ‘/’ operation
 loses information about the signs of its inputs.  Because the quotient
 is negative, we know exactly one of the inputs was negative, but we
 can’t tell which one.  There is an ‘f T’ [‘arctan2’] function which
 computes the inverse tangent of the quotient of a pair of numbers.
 Since you feed it the two original numbers, it has enough information to
 give you a full 360-degree answer.
 
      2:  0.89879    1:  116.       3:  116.       2:  116.       1:  180.
      1:  -0.43837       .          2:  -0.89879   1:  -64.           .
          .                         1:  0.43837        .
                                        .
 
          U U            f T         M-<RET> M-2 n       f T            -
 
 The resulting angles differ by 180 degrees; in other words, they point
 in opposite directions, just as we would expect.
 
    The <META>-<RET> we used in the third step is the “last-arguments”
 command.  It is sort of like Undo, except that it restores the arguments
 of the last command to the stack without removing the command’s result.
 It is useful in situations like this one, where we need to do several
 operations on the same inputs.  We could have accomplished the same
 thing by using ‘M-2 <RET>’ to duplicate the top two stack elements right
 after the ‘U U’, then a pair of ‘M-<TAB>’ commands to cycle the 116 up
 around the duplicates.
 
    A similar identity is supposed to hold for hyperbolic sines and
 cosines, except that it is the _difference_ ‘cosh(x)^2 - sinh(x)^2’ that
 always equals one.  Let’s try to verify this identity.
 
      2:  -64        2:  -64        2:  -64        2:  9.7192e54  2:  9.7192e54
      1:  -64        1:  -3.1175e27 1:  9.7192e54  1:  -64        1:  9.7192e54
          .              .              .              .              .
 
       64 n <RET> <RET>      H C            2 ^            <TAB>            H S 2 ^
 
 Something’s obviously wrong, because when we subtract these numbers the
 answer will clearly be zero!  But if you think about it, if these
 numbers _did_ differ by one, it would be in the 55th decimal place.  The
 difference we seek has been lost entirely to roundoff error.
 
    We could verify this hypothesis by doing the actual calculation with,
 say, 60 decimal places of precision.  This will be slow, but not
 enormously so.  Try it if you wish; sure enough, the answer is 0.99999,
 reasonably close to 1.
 
    Of course, a more reasonable way to verify the identity is to use a
 more reasonable value for ‘x’!
 
    Some Calculator commands use the Hyperbolic prefix for other
 purposes.  The logarithm and exponential functions, for example, work to
 the base ‘e’ normally but use base-10 instead if you use the Hyperbolic
 prefix.
 
      1:  1000       1:  6.9077     1:  1000       1:  3
          .              .              .              .
 
          1000           L              U              H L
 
 First, we mistakenly compute a natural logarithm.  Then we undo and
 compute a common logarithm instead.
 
    The ‘B’ key computes a general base-B logarithm for any value of B.
 
      2:  1000       1:  3          1:  1000.      2:  1000.      1:  6.9077
      1:  10             .              .          1:  2.71828        .
          .                                            .
 
       1000 <RET> 10       B              H E            H P            B
 
 Here we first use ‘B’ to compute the base-10 logarithm, then use the
 “hyperbolic” exponential as a cheap hack to recover the number 1000,
 then use ‘B’ again to compute the natural logarithm.  Note that ‘P’ with
 the hyperbolic prefix pushes the constant ‘e’ onto the stack.
 
    You may have noticed that both times we took the base-10 logarithm of
 1000, we got an exact integer result.  Calc always tries to give an
 exact rational result for calculations involving rational numbers where
 possible.  But when we used ‘H E’, the result was a floating-point
 number for no apparent reason.  In fact, if we had computed ‘10 <RET> 3
 ^’ we _would_ have gotten an exact integer 1000.  But the ‘H E’ command
 is rigged to generate a floating-point result all of the time so that
 ‘1000 H E’ will not waste time computing a thousand-digit integer when
 all you probably wanted was ‘1e1000’.
 
    (•) *Exercise 2.*  Find a pair of integer inputs to the ‘B’ command
 for which Calc could find an exact rational result but doesn’t.  See
 2 Arithmetic Answer 2.  (•)
 
    The Calculator also has a set of functions relating to combinatorics
 and statistics.  You may be familiar with the “factorial” function,
 which computes the product of all the integers up to a given number.
 
      1:  100        1:  93326215443...    1:  100.       1:  9.3326e157
          .              .                     .              .
 
          100            !                     U c f          !
 
 Recall, the ‘c f’ command converts the integer or fraction at the top of
 the stack to floating-point format.  If you take the factorial of a
 floating-point number, you get a floating-point result accurate to the
 current precision.  But if you give ‘!’ an exact integer, you get an
 exact integer result (158 digits long in this case).
 
    If you take the factorial of a non-integer, Calc uses a generalized
 factorial function defined in terms of Euler’s Gamma function ‘gamma(n)’
 (which is itself available as the ‘f g’ command).
 
      3:  4.         3:  24.               1:  5.5        1:  52.342777847
      2:  4.5        2:  52.3427777847         .              .
      1:  5.         1:  120.
          .              .
 
                         M-3 !              M-0 <DEL> 5.5       f g
 
 Here we verify the identity ‘N! = gamma(N+1)’.
 
    The binomial coefficient N-choose-M is defined by ‘n! / m! (n-m)!’
 for all reals ‘n’ and ‘m’.  The intermediate results in this formula can
 become quite large even if the final result is small; the ‘k c’ command
 computes a binomial coefficient in a way that avoids large intermediate
 values.
 
    The ‘k’ prefix key defines several common functions out of
 combinatorics and number theory.  Here we compute the binomial
 coefficient 30-choose-20, then determine its prime factorization.
 
      2:  30         1:  30045015   1:  [3, 3, 5, 7, 11, 13, 23, 29]
      1:  20             .              .
          .
 
       30 <RET> 20         k c            k f
 
 You can verify these prime factors by using ‘V R *’ to multiply together
 the elements of this vector.  The result is the original number,
 30045015.
 
    Suppose a program you are writing needs a hash table with at least
 10000 entries.  It’s best to use a prime number as the actual size of a
 hash table.  Calc can compute the next prime number after 10000:
 
      1:  10000      1:  10007      1:  9973
          .              .              .
 
          10000          k n            I k n
 
 Just for kicks we’ve also computed the next prime _less_ than 10000.
 
    SeeFinancial Functions, for a description of the Calculator
 commands that deal with business and financial calculations (functions
 like ‘pv’, ‘rate’, and ‘sln’).
 
    SeeBinary Functions, to read about the commands for operating on
 binary numbers (like ‘and’, ‘xor’, and ‘lsh’).