Back to tutorial index

Formatting output


Topics in this lab

Introduction

One of the big differences between scientific computing and other branches of computer science is that scientific computing deals with floating point numbers to a much greater extent. One consequence of this is that the number of significant digits that appear in a result that we print out if very important.

Back to the top

Using the 'format' statement

A quick way to change the formatting behavior in Matlab's command line is to use the format key word.
To see approximately five digits displayed, we can use the short as a keyword argument to format.

format short
pi
ans =

    3.1416

This format is what is called fixed point formatting. The decimal place is fixed in place, regardless of the value of the number, and approximately five significant figures are shown, with four digits after the decimal place. If we scale the number to make it either larger or smaller, we see that the location of the decimal point remains fixed, as long as the total number of digits does not exceed 7, (roughly) or drop below about 2.

format short
pi/10
ans =

    0.3142

pi/100
ans =

    0.0314

pi/1000
ans =

    0.0031

10*pi
ans =

   31.4159

100*pi
ans =

  314.1593

Using the keyword long produces roughly the same results, but with about 15 digits after the decimal place.

format long
pi
ans =

   3.141592653589793

pi/10
ans =

   0.314159265358979

pi/100
ans =

   0.031415926535898

10*pi
ans =

  31.415926535897931

In all cases, the decimal place shifts to the right or left in the expected way.

However, as soon as we scale the number by larger values, we see that the formatting changes to exponential notation, to accommodate the fact that more than four digits would be needed before the decimal, or the value would require more than two leading zeros.

format short
1000*pi
ans =

   3.1416e+03

format long
1000*pi
ans =

     3.141592653589793e+03

In both cases, the formatting changed to a floating point notation (sometimes called exponential or scientific notation). The decimal point "floats" so that the there is exactly one digit before the decimal and four or 16 after the decimal.

To explicitly specify scientific notation, use a trailing "e" for either the long or short versions of the format statement. With this keyword, you will always get exponential notation, regardless of the magnitude of the number.

format short e
pi
ans =

   3.1416e+00

pi/10
ans =

   3.1416e-01

10*pi
ans =

   3.1416e+01

format long e
pi
ans =

     3.141592653589793e+00

pi/10
ans =

     3.141592653589793e-01

10*pi
ans =

     3.141592653589793e+01

In general, the format statement should only be used for quick formatting at the command line, and should never be used in a script to print out results of a calculation. As you would see after some experimentation the rules for formatting using format are not clear, and the result is somewhat unpredictable. Furthermore, there seems to be no way to print a numbers like $10000\pi$ or $\pi/10000$ using fixed point notation, or to specify that exactly 8 digits after the decimal should be shown.

We can completely control the formatting behavior of numbers and strings by using the fprintf command, which we discuss next.

Back to the top

Formatting - using 'fprintf' for scalar values

In scientific computing, the manner in which we format output (tables of numbers for example) depends on what we plan to do with those numbers. If all you want to see is whether a number is positive or negative, you might only need very few digits. But if you want to see how how many digits of accuracy you get in a particular approximation, you might want the full 16 digits available. Often, when working with measurements of physical quantities, you want your displayed values to reflect the number of significant digits or level or precision in your measurements.

For this reason, it is useful to have a flexible way of presenting numerical output. The fprintf command is particularly useful. It does not take arguments in the traditional sense, but instead uses format strings to indicate how text and numbers should be printed.

Here is how we could use the fprintf to format the values from the examples above. This time, we will specify exactly how many digits appear after the decimal, and whether to use fixed or floating point notation.

Fixed point notation, using 8 digits after the decimal.

fprintf('%16.8f\n',pi);
      3.14159265
fprintf('%16.8f\n',pi/1000);
      0.00314159
fprintf('%16.8f\n',1000*pi);
   3141.59265359

Notice that in each case, we get exactly 8 digits after the decimal place, and that the decimal remains fixed in the location needed to accurately represent the value. Also notice, however, that the number of significant figures we show varies with each example above. When we just printed $\pi$, we saw 9 significant figures (1 before and 8 after the decimal). But when printing $\pi/1000$, we saw only 6 significant figures and when printing $\pi/1000$, we see 12 significant figures.

Here are a few more extreme examples to illustrate this behavior.

fprintf('%16.8f\n',pi/1e12);   % looks like 0, but it isn't!
      0.00000000
fprintf('%24.8f\n',1e12*pi);   % Lots of digits of pi.  Are they all correct?
  3141592653589.79296875

Here is how we might use fprintf to print a table of numbers. In this example, we print the same number in several different ways.

x = -2e2 + 4e2*rand(1,5);  % Numbers in [-200,200]
fprintf('XX|XXXXX.XX|XXXXXXX.XXXXXXXX|XXX.XXXXXXXXXXXXXXXXe+NN|\n');
for i = 1:5,
  fprintf('%2d|%8.2f|%16.8f|%24.16e|\n',i,x(i), x(i),x(i));
end;
XX|XXXXX.XX|XXXXXXX.XXXXXXXX|XXX.XXXXXXXXXXXXXXXXe+NN|
 1|  -33.09|    -33.09317237| -3.3093172366252190e+01|
 2| -180.14|   -180.13822787| -1.8013822786970314e+02|
 3|  161.09|    161.08644397|  1.6108644396611243e+02|
 4|  177.91|    177.91487589|  1.7791487588865840e+02|
 5|   -3.65|     -3.65436301| -3.6543630127680160e+00|

The first argument to fprintf in this example is a string. This string contains four format strings, e.g. '%2d', '%8.2f', '%16.8f' and '%24.16e'. The first value in the format string is the field width and the second value is the number of digits after the decimal place to display. The field width is exactly the number of characters between the vertical bars ('|'), including any the decimal point, a possible '-' or '+' (a minus or plus sign) and any characters needed to represent floating point numbers (e.g. the 'e+02' in the above example). The Xs at the top of the table are here to indicate the field width.

In the above example, the format strings 'd','f', and 'e' are used. These are the most common, and are to be used with integers, fixed point formatting, and floating point (scietific notation) formatting, respectively.

Notice what can happen if we don't format properly. In following examples, we show several formatting "mistakes", and a way to correct them.

Example 1


We are using a fixed point notation, but are not plotting enough digits to see that our number is not zero.

a = 1.456e-10;
fprintf('|XXXXXXXXXX|\n');
fprintf('|%10.4f|\n',a);      % Using 'f' in this case only shows zero digits
fprintf('|%10.3e|\n',a);      % Show non-zero digits
|XXXXXXXXXX|
|    0.0000|
| 1.456e-10|

Example 2


Here, we have again not specified enough digits, and the print statement is rounding up to the nearest value that can be printed using the format string we have specified.

b = 4.0098734;
fprintf('|XXXXXXXXXX|\n');
fprintf('|%10.2f|\n',b);    % Not wrong, but just be aware that fprintf rounds up
|XXXXXXXXXX|
|      4.01|

Example 3


In this case, we are using the integer format string 'd', but our number is not an integer. The fprintf statement then reverts to a default format %12.6e.

c = 7.631;
fprintf('|XXXXXXXXXX|\n');
fprintf('|%10d|\n',c);    % The integer format string ('d') is over-ridden.
fprintf('|%10.3f|\n',c);  % Use the 'f' format string instead.
|XXXXXXXXXX|
|7.631000e+00|
|     7.631|

Example 4


And when we do not specify a field width sufficiently wide to contain the number of digits that should be printed out, the specified field width is overrun.

d = -456745e8;
fprintf('|XXXXXXXXXX|\n');
fprintf('|%10f|\n',d);     % Field width too small; decimal digits are shown
fprintf('|XXXXXXXXXXXXXXX|\n');
fprintf('|%15.0f|\n',d);   % Increase field width; don't show decimal digits
|XXXXXXXXXX|
|-45674500000000.000000|
|XXXXXXXXXXXXXXX|
|-45674500000000|

Example 5


Finally, if we fail to take into account the width needed for the extra characters involved in the formatting of a floating point number, we also overrun the specified field width.

e = pi*1e-4;
fprintf('|XXXXXXXXXX|\n');
fprintf('|%10.9e|\n',e);      % Field width not large enough
fprintf('|XXXXXXXXXXXXXXX|\n');
fprintf('|%15.9e|\n',e);      % Increase size of field.
|XXXXXXXXXX|
|3.141592654e-04|
|XXXXXXXXXXXXXXX|
|3.141592654e-04|

Back to the top

Formatting - using 'fprintf' for arrays


The command fprintf also works on arrays. In this case, the format string is applied to each entry of the array.

x = -1 + 2*rand(1,5);
fprintf('|XXXXXXXX|\n');
fprintf('|%8.4f|\n',x);      % x is an array
|XXXXXXXX|
| -0.0215|
| -0.3246|
|  0.8001|
| -0.2615|
| -0.7776|

One final formatting tip is the use of the "string" formatting to list a set of values in a nice way. Here is a simple example.

fprintf('%16s %10.1f\n','Temperature (K)',301.3);
fprintf('%16s %10.2e\n','Energy (J)',1.24e6);
fprintf('%16s %10.2f\n','Density (kg/m3)',1.21);
fprintf('%16s %10.2f\n','Pressure (bar)',2.13);
 Temperature (K)      301.3
      Energy (J)   1.24e+06
 Density (kg/m3)       1.21
  Pressure (bar)       2.13

By using the string format string 's', we can right justify the label for each value, which leads to a nicely formatted table.

Back to the top

Lab exercises

In this lab, you will practice using the fprintf statements, and using conditional statements.
  1. Use the fprintf to print out the following numbers.
    a = 5
    b = 14.567
    c = exp(12)
    d = 2^(-12)
    

    Your output should look exactly like the second line in the output displayed below :

    |XXXXX|XXXXXXXXXX|XXXXXXXXXXXX|XXXXXXXXXXXXXX|
    |    5|    14.567|  1.6275e+05|3.05175781e-05|
    

    The 'X's are placed as a guide and don't need to be printed. Count the field width of the formatted string to make sure you have correctly spaced the digits before and after the decimal, and any additional characters needed for scientific notation.

Compare your results with the solutions.

Back to the top

Get the code

Do you want to try the above code fragments on your own? Download the Matlab script that produces this page here. (lab_12.m)

Powered by MathJax

Published with MATLAB® 8.5