Previous: Undo Tutorial, Up: Basic 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 ` (back-quote) 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? See 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? See 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? See 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? See 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.