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

To change Matlab's default behavior, use the format statement.

format long
1/3
ans =
   0.333333333333333
1/3000
ans =
     3.333333333333333e-04

We can return to the default shortened format by using the short format option.

format short
1/3
ans =
    0.3333

You can specify exponential notational with a trailing "e" for either the long or short versions of the format statement.

format long e
1/12
ans =
     8.333333333333333e-02
format short e
1/12
ans =
   8.3333e-02

Back to the top

Formatting - using 'fprintf'

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.

For this reason, it is useful to have a flexible way of presenting numerical output. We have already learned the format statement. Now we are going to learn a more sophisticated way of printing numbers to the screen or to a file. 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 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| -140.75|   -140.74954935| -1.4074954934790074e+02|
 2|  115.60|    115.59673565|  1.1559673565070500e+02|
 3| -187.73|   -187.73244361| -1.8773244361359698e+02|
 4| -196.11|   -196.11471589| -1.9611471588681820e+02|
 5|  -30.86|    -30.86331752| -3.0863317521149384e+01|

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|

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.7371|
| -0.7668|
| -0.3891|
| -0.3915|
| -0.8388|

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.4