calc: Modes Tutorial

 
 3.1.4 Mode-Setting Commands
 ---------------------------
 
 Calc has many types of “modes” that affect the way it interprets your
 commands or the way it displays data.  We have already seen one mode,
 namely Algebraic mode.  There are many others, too; we’ll try some of
 the most common ones here.
 
    Perhaps the most fundamental mode in Calc is the current “precision”.
 Notice the ‘12’ on the Calc window’s mode line:
 
      --%*-Calc: 12 Deg       (Calculator)----All------
 
 Most of the symbols there are Emacs things you don’t need to worry
 about, but the ‘12’ and the ‘Deg’ are mode indicators.  The ‘12’ means
 that calculations should always be carried to 12 significant figures.
 That is why, when we type ‘1 <RET> 7 /’, we get ‘0.142857142857’ with
 exactly 12 digits, not counting leading and trailing zeros.
 
    You can set the precision to anything you like by pressing ‘p’, then
 entering a suitable number.  Try pressing ‘p 30 <RET>’, then doing ‘1
 <RET> 7 /’ again:
 
      1:  0.142857142857
      2:  0.142857142857142857142857142857
          .
 
    Although the precision can be set arbitrarily high, Calc always has
 to have _some_ value for the current precision.  After all, the true
 value ‘1/7’ is an infinitely repeating decimal; Calc has to stop
 somewhere.
 
    Of course, calculations are slower the more digits you request.
 Press ‘p 12’ now to set the precision back down to the default.
 
    Calculations always use the current precision.  For example, even
 though we have a 30-digit value for ‘1/7’ on the stack, if we use it in
 a calculation in 12-digit mode it will be rounded down to 12 digits
 before it is used.  Try it; press <RET> to duplicate the number, then
 ‘1 +’.  Notice that the <RET> key didn’t round the number, because it
 doesn’t do any calculation.  But the instant we pressed ‘+’, the number
 was rounded down.
 
      1:  0.142857142857
      2:  0.142857142857142857142857142857
      3:  1.14285714286
          .
 
 In fact, since we added a digit on the left, we had to lose one digit on
 the right from even the 12-digit value of ‘1/7’.
 
    How did we get more than 12 digits when we computed ‘2^3^4’?  The
 answer is that Calc makes a distinction between “integers” and
 “floating-point” numbers, or “floats”.  An integer is a number that does
 not contain a decimal point.  There is no such thing as an “infinitely
 repeating fraction integer,” so Calc doesn’t have to limit itself.  If
 you asked for ‘2^10000’ (don’t try this!), you would have to wait a long
 time but you would eventually get an exact answer.  If you ask for
 ‘2.^10000’, you will quickly get an answer which is correct only to 12
 places.  The decimal point tells Calc that it should use floating-point
 arithmetic to get the answer, not exact integer arithmetic.
 
    You can use the ‘F’ (‘calc-floor’) command to convert a
 floating-point value to an integer, and ‘c f’ (‘calc-float’) to convert
 an integer to floating-point form.
 
    Let’s try entering that last calculation:
 
      1:  2.         2:  2.         1:  1.99506311689e3010
          .          1:  10000          .
                         .
 
        2.0 <RET>          10000 <RET>      ^
 
 Notice the letter ‘e’ in there.  It represents “times ten to the power
 of,” and is used by Calc automatically whenever writing the number out
 fully would introduce more extra zeros than you probably want to see.
 You can enter numbers in this notation, too.
 
      1:  2.         2:  2.         1:  1.99506311678e3010
          .          1:  10000.         .
                         .
 
        2.0 <RET>          1e4 <RET>        ^
 
 Hey, the answer is different!  Look closely at the middle columns of the
 two examples.  In the first, the stack contained the exact integer
 ‘10000’, but in the second it contained a floating-point value with a
 decimal point.  When you raise a number to an integer power, Calc uses
 repeated squaring and multiplication to get the answer.  When you use a
 floating-point power, Calc uses logarithms and exponentials.  As you can
 see, a slight error crept in during one of these methods.  Which one
 should we trust?  Let’s raise the precision a bit and find out:
 
          .          1:  2.         2:  2.         1:  1.995063116880828e3010
                         .          1:  10000.         .
                                        .
 
       p 16 <RET>        2. <RET>           1e4            ^    p 12 <RET>
 
 Presumably, it doesn’t matter whether we do this higher-precision
 calculation using an integer or floating-point power, since we have
 added enough “guard digits” to trust the first 12 digits no matter what.
 And the verdict is... Integer powers were more accurate; in fact, the
 result was only off by one unit in the last place.
 
    Calc does many of its internal calculations to a slightly higher
 precision, but it doesn’t always bump the precision up enough.  In each
 case, Calc added about two digits of precision during its calculation
 and then rounded back down to 12 digits afterward.  In one case, it was
 enough; in the other, it wasn’t.  If you really need X digits of
 precision, it never hurts to do the calculation with a few extra guard
 digits.
 
    What if we want guard digits but don’t want to look at them?  We can
 set the “float format”.  Calc supports four major formats for
 floating-point numbers, called “normal”, “fixed-point”, “scientific
 notation”, and “engineering notation”.  You get them by pressing ‘d n’,
 ‘d f’, ‘d s’, and ‘d e’, respectively.  In each case, you can supply a
 numeric prefix argument which says how many digits should be displayed.
 As an example, let’s put a few numbers onto the stack and try some
 different display modes.  First, use ‘M-0 <DEL>’ to clear the stack,
 then enter the four numbers shown here:
 
      4:  12345      4:  12345      4:  12345      4:  12345      4:  12345
      3:  12345.     3:  12300.     3:  1.2345e4   3:  1.23e4     3:  12345.000
      2:  123.45     2:  123.       2:  1.2345e2   2:  1.23e2     2:  123.450
      1:  12.345     1:  12.3       1:  1.2345e1   1:  1.23e1     1:  12.345
          .              .              .              .              .
 
         d n          M-3 d n          d s          M-3 d s        M-3 d f
 
 Notice that when we typed ‘M-3 d n’, the numbers were rounded down to
 three significant digits, but then when we typed ‘d s’ all five
 significant figures reappeared.  The float format does not affect how
 numbers are stored, it only affects how they are displayed.  Only the
 current precision governs the actual rounding of numbers in the
 Calculator’s memory.
 
    Engineering notation, not shown here, is like scientific notation
 except the exponent (the power-of-ten part) is always adjusted to be a
 multiple of three (as in “kilo,” “micro,” etc.).  As a result there will
 be one, two, or three digits before the decimal point.
 
    Whenever you change a display-related mode, Calc redraws everything
 in the stack.  This may be slow if there are many things on the stack,
 so Calc allows you to type shift-‘H’ before any mode command to prevent
 it from updating the stack.  Anything Calc displays after the
 mode-changing command will appear in the new format.
 
      4:  12345      4:  12345      4:  12345      4:  12345      4:  12345
      3:  12345.000  3:  12345.000  3:  12345.000  3:  1.2345e4   3:  12345.
      2:  123.450    2:  123.450    2:  1.2345e1   2:  1.2345e1   2:  123.45
      1:  12.345     1:  1.2345e1   1:  1.2345e2   1:  1.2345e2   1:  12.345
          .              .              .              .              .
 
          H d s          <DEL> U          <TAB>            d <SPC>          d n
 
 Here the ‘H d s’ command changes to scientific notation but without
 updating the screen.  Deleting the top stack entry and undoing it back
 causes it to show up in the new format; swapping the top two stack
 entries reformats both entries.  The ‘d <SPC>’ command refreshes the
 whole stack.  The ‘d n’ command changes back to the normal float format;
 since it doesn’t have an ‘H’ prefix, it also updates all the stack
 entries to be in ‘d n’ format.
 
    Notice that the integer ‘12345’ was not affected by any of the float
 formats.  Integers are integers, and are always displayed exactly.
 
    Large integers have their own problems.  Let’s look back at the
 result of ‘2^3^4’.
 
      2417851639229258349412352
 
 Quick—how many digits does this have?  Try typing ‘d g’:
 
      2,417,851,639,229,258,349,412,352
 
 Now how many digits does this have?  It’s much easier to tell!  We can
 actually group digits into clumps of any size.  Some people prefer ‘M-5
 d g’:
 
      24178,51639,22925,83494,12352
 
    Let’s see what happens to floating-point numbers when they are
 grouped.  First, type ‘p 25 <RET>’ to make sure we have enough precision
 to get ourselves into trouble.  Now, type ‘1e13 /’:
 
      24,17851,63922.9258349412352
 
 The integer part is grouped but the fractional part isn’t.  Now try ‘M--
 M-5 d g’ (that’s meta-minus-sign, meta-five):
 
      24,17851,63922.92583,49412,352
 
    If you find it hard to tell the decimal point from the commas, try
 changing the grouping character to a space with ‘d , <SPC>’:
 
      24 17851 63922.92583 49412 352
 
    Type ‘d , ,’ to restore the normal grouping character, then ‘d g’
 again to turn grouping off.  Also, press ‘p 12’ to restore the default
 precision.
 
    Press ‘U’ enough times to get the original big integer back.  (Notice
 that ‘U’ does not undo each mode-setting command; if you want to undo a
 mode-setting command, you have to do it yourself.)  Now, type ‘d r 16
 <RET>’:
 
      16#200000000000000000000
 
 The number is now displayed in “hexadecimal”, or “base-16” form.
 Suddenly it looks pretty simple; this should be no surprise, since we
 got this number by computing a power of two, and 16 is a power of 2.  In
 fact, we can use ‘d r 2 <RET>’ to see it in actual binary form:
 
      2#1000000000000000000000000000000000000000000000000000000 ...
 
 We don’t have enough space here to show all the zeros!  They won’t fit
 on a typical screen, either, so you will have to use horizontal
 scrolling to see them all.  Press ‘<’ and ‘>’ to scroll the stack window
 left and right by half its width.  Another way to view something large
 is to press ‘`’ (grave accent) to edit the top of stack in a separate
 window.  (Press ‘C-c C-c’ when you are done.)
 
    You can enter non-decimal numbers using the ‘#’ symbol, too.  Let’s
 see what the hexadecimal number ‘5FE’ looks like in binary.  Type
 ‘16#5FE’ (the letters can be typed in upper or lower case; they will
 always appear in upper case).  It will also help to turn grouping on
 with ‘d g’:
 
      2#101,1111,1110
 
    Notice that ‘d g’ groups by fours by default if the display radix is
 binary or hexadecimal, but by threes if it is decimal, octal, or any
 other radix.
 
    Now let’s see that number in decimal; type ‘d r 10’:
 
      1,534
 
    Numbers are not _stored_ with any particular radix attached.  They’re
 just numbers; they can be entered in any radix, and are always displayed
 in whatever radix you’ve chosen with ‘d r’.  The current radix applies
 to integers, fractions, and floats.
 
    (•) *Exercise 1.*  Your friend Joe tried to enter one-third as
 ‘3#0.1’ in ‘d r 3’ mode with a precision of 12.  He got ‘3#0.0222222...’
 (with 25 2’s) in the display.  When he multiplied that by three, he got
 ‘3#0.222222...’ instead of the expected ‘3#1’.  Next, Joe entered
 ‘3#0.2’ and, to his great relief, saw ‘3#0.2’ on the screen.  But when
 he typed ‘2 /’, he got ‘3#0.10000001’ (some zeros omitted).  What’s
 going on here?  See1 Modes Answer 1.  (•)
 
    (•) *Exercise 2.*  Scientific notation works in non-decimal modes in
 the natural way (the exponent is a power of the radix instead of a power
 of ten, although the exponent itself is always written in decimal).
 Thus ‘8#1.23e3 = 8#1230.0’.  Suppose we have the hexadecimal number
 ‘f.e8f’ times 16 to the 15th power: We write ‘16#f.e8fe15’.  What is
 wrong with this picture?  What could we write instead that would work
 better?  See2 Modes Answer 2.  (•)
 
    The ‘m’ prefix key has another set of modes, relating to the way Calc
 interprets your inputs and does computations.  Whereas ‘d’-prefix modes
 generally affect the way things look, ‘m’-prefix modes affect the way
 they are actually computed.
 
    The most popular ‘m’-prefix mode is the “angular mode”.  Notice the
 ‘Deg’ indicator in the mode line.  This means that if you use a command
 that interprets a number as an angle, it will assume the angle is
 measured in degrees.  For example,
 
      1:  45         1:  0.707106781187   1:  0.500000000001    1:  0.5
          .              .                    .                     .
 
          45             S                    2 ^                   c 1
 
 The shift-‘S’ command computes the sine of an angle.  The sine of 45
 degrees is ‘sqrt(2)/2’; squaring this yields ‘2/4 = 0.5’.  However,
 there has been a slight roundoff error because the representation of
 ‘sqrt(2)/2’ wasn’t exact.  The ‘c 1’ command is a handy way to clean up
 numbers in this case; it temporarily reduces the precision by one digit
 while it re-rounds the number on the top of the stack.
 
    (•) *Exercise 3.*  Your friend Joe computed the sine of 45 degrees as
 shown above, then, hoping to avoid an inexact result, he increased the
 precision to 16 digits before squaring.  What happened?  See3 Modes
 Answer 3.  (•)
 
    To do this calculation in radians, we would type ‘m r’ first.  (The
 indicator changes to ‘Rad’.)  45 degrees corresponds to ‘pi/4’ radians.
 To get ‘pi’, press the ‘P’ key.  (Once again, this is a shifted capital
 ‘P’.  Remember, unshifted ‘p’ sets the precision.)
 
      1:  3.14159265359   1:  0.785398163398   1:  0.707106781187
          .                   .                .
 
          P                   4 /       m r    S
 
    Likewise, inverse trigonometric functions generate results in either
 radians or degrees, depending on the current angular mode.
 
      1:  0.707106781187   1:  0.785398163398   1:  45.
          .                    .                    .
 
          .5 Q        m r      I S        m d       U I S
 
 Here we compute the Inverse Sine of ‘sqrt(0.5)’, first in radians, then
 in degrees.
 
    Use ‘c d’ and ‘c r’ to convert a number from radians to degrees and
 vice-versa.
 
      1:  45         1:  0.785398163397     1:  45.
          .              .                      .
 
          45             c r                    c d
 
    Another interesting mode is “Fraction mode”.  Normally, dividing two
 integers produces a floating-point result if the quotient can’t be
 expressed as an exact integer.  Fraction mode causes integer division to
 produce a fraction, i.e., a rational number, instead.
 
      2:  12         1:  1.33333333333    1:  4:3
      1:  9              .                    .
          .
 
       12 <RET> 9          /          m f       U /      m f
 
 In the first case, we get an approximate floating-point result.  In the
 second case, we get an exact fractional result (four-thirds).
 
    You can enter a fraction at any time using ‘:’ notation.  (Calc uses
 ‘:’ instead of ‘/’ as the fraction separator because ‘/’ is already used
 to divide the top two stack elements.)  Calculations involving fractions
 will always produce exact fractional results; Fraction mode only says
 what to do when dividing two integers.
 
    (•) *Exercise 4.*  If fractional arithmetic is exact, why would you
 ever use floating-point numbers instead?  See4 Modes Answer 4.  (•)
 
    Typing ‘m f’ doesn’t change any existing values in the stack.  In the
 above example, we had to Undo the division and do it over again when we
 changed to Fraction mode.  But if you use the evaluates-to operator you
 can get commands like ‘m f’ to recompute for you.
 
      1:  12 / 9 => 1.33333333333    1:  12 / 9 => 1.333    1:  12 / 9 => 4:3
          .                              .                      .
 
         ' 12/9 => <RET>                   p 4 <RET>                m f
 
 In this example, the righthand side of the ‘=>’ operator on the stack is
 recomputed when we change the precision, then again when we change to
 Fraction mode.  All ‘=>’ expressions on the stack are recomputed every
 time you change any mode that might affect their values.