First Steps in Programming - Division Using Floating-Point Values
(Page 7 of 13 )
As you’ve seen, division operations with integer operands always produce an integer result. Unless the left operand of a division is an exact multiple of the right operand, the result will be inherently inaccurate. Of course, the way integer division works is an advantage if you’re distributing cookies to children, but it isn’t particularly useful when you want to cut a 10-foot plank into four equal pieces. This is a job for floating-point values.
Division operations with floating-point values will give you an exact result—at least, a result that is as exact as it can be with a fixed number of digits of precision. The next example illustrates how division operations work with variables of type float.
Try It Out: Division with Values of Type float
Here’s a simple example that just divides one floating-point value by another and displays the result:
/* Program 2.7 Division with float values */
#include <stdio.h>
void main()
{
float plank_length = 10.0f; /* In feet */
float piece_count = 4.0f; /* Number of equal pieces */
float piece_length = 0.0f; /* Length of a piece in feet
*/
piece_length = plank_length/piece_ccount;
printf("A plank %f feet long can be cut into %f pieces %f
feet long.",
plank_length, piece_count, piece_length);
}
This program should produce the following output:
======================================================
A plank 10.000000 feet long can be cut into 4.000000 pieces 2.500000 feet long.
=====================================================
HOW IT WORKS
You shouldn’t have any trouble understanding how you chop the plank into equal pieces. Note that you use a new format specifier for values of type float in the printf() statement:
printf("A plank %f feet long can be cut into %f pieces %f
feet long.",
plank_length, piece_count, piece_length);
You use the format specifier %f to display floating-point values. In general, the format specifier that you use must correspond to the type of value that you’re outputting. If you output a value of type float with the specifier %d that’s intended for use with integer values, you’ll get rubbish. This is because the float value will be interpreted as an integer, which it isn’t. Similarly, if you use %f with a value of an integer type, then you’ll also get rubbish as output.
More on Format Specifiers
In the last example, you got a lot of decimal places in the output that you really didn’t need. You may be good with a rule and a saw, but you aren’t going to be able to cut the plank with a length of 2.500000 feet rather than 2.500001 feet. You can specify the number of places that you want to see after the decimal point in the format specifier. To obtain the output to two decimal places, you would write the format specifier as %.2f. To get three decimal places, you would write %.3f.
You can change the printf() statement in the last example so that it will produce more suitable output:
printf("A plank %.2f feet long can be cut into %.0f
pieces %.2f feet long.",
plank_length, piece_count, piece_length);
The first format specification corresponds to the plank_length variable and will produce output with two decimal places. The second specification will produce no decimal places—this makes sense here because the piece_count value is a whole number. The last specification is the same as the first. Thus, if you run the example with this version of the last statement, the output will be
=======================================================
A plank 10.00 feet long can be cut into 4 pieces 2.50 feet long.
=======================================================
This is much more appropriate and looks a lot better.
The field width for the output has been determined by default. The printf() function works out how many character positions will be required for a value, given the number of decimal places you specify. However, you may want to decide the field width yourself. This will be the case if you want to output a column of values so they line up. If you let the printf() function work out the field width, you’re likely to get a ragged column of output. A more general form of the format specifier for floating-point values can be written like this:
%[width][.precision]f
The square brackets here aren’t part of the specification. They enclose bits of the specification that are optional, so you can omit either the width or the.precision, or both. The width value is an integer specifying the total number of characters in the output: the field width. The precision value is an integer specifying the number of decimal places that are to appear after the decimal point.
You could rewrite printf() from the last example to specify the field width as well as the number of digits you want after the decimal point, for example:
printf("A %8.2f plank foot can be cut into %5.0f pieces %
6.2f feet long.",
plank_length, piece_count, piece_length);
I changed the text a little to get it to fit across the page here. The first value now will have a field width of 8 and two decimal places after the decimal point. The second value, which is the count of the number of pieces, will have a field width of 5 characters and no decimal places. The third value will be presented in a field width of 6 with two decimal places.
When you specify the field width, the value will be right-aligned by default. If you want the value to be left-aligned in the field, you just put a minus sign following the %. For instance, the specification %-10.4f will output a floating-point value left-aligned in a field width of 10 characters with four digits following the decimal point.
Note that you can specify a field width and the alignment in the field with a specification for outputting an integer value. For example, %-15d specifies an integer value will be presented left-aligned in a field width of 15 characters.
There’s more to format specifiers than I’ve introduced here, and you’ll learn more about them later. Try some variations out using the previous example. In particular, see what happens when the field width is too small for the value.
More Complex Expressions You know that arithmetic can get a lot more complicated than just dividing a couple of numbers. In fact, if that was all you were trying to do, then you may as well use paper and pencil. Now that you have the tools of addition, subtraction, multiplication, and division at your disposal, you can start to do some really heavy calculations.
For these more complicated calculations, you’ll need more control over the sequence of operations when an expression is evaluated. Parentheses provide you with this capability. They can also help to make expressions clearer when they’re getting intricate.
Parentheses in Arithmetic Expressions
You can use parentheses in arithmetic expressions, and they work much as you’d expect. Subexpressions contained within parentheses are evaluated in sequence from the innermost pair of parentheses to the outermost, with the normal rules that you’re used to for operator precedence, where multiplication and division happen before addition or subtraction. Therefore, the expression 2 * (3 + 3 * (5 + 4)) evaluates to 60. You start with the expression 5 + 4, which produces 9. Then you multiply that by 3, which gives 27. Then you add 3 to that total (giving 30) and multiply the whole lot by 2.
You can also insert spaces to separate operands from operators to make your arithmetic statements more readable. If you’re not quite sure of how an expression will be evaluated according to the precedence rules, you can always put in some parentheses to make sure it produces the result you want.
Try It Out: Arithmetic in Action
This time you’ll have a go at calculating the circumference and area of a circular table from an input value for its diameter radius. You may remember from elementary math the equations to calculate the area and circumference of a circle using π or pi (circumference = 2πr and area = πr2, whereris the radius). If you don’t, then don’t worry. This isn’t a math book, so just look at how the program works.
/* Program 2.8 calculations on a table */
#include <studio.h>
void main()
{
float radius = 0.0f; /* The radius of the
table */
float diameter = 0.0f; /* The diameter of the
table */
float circumference = 0.0f; /* The circumference of
the table */
float area = 0.0f; /* The area of a circle
*/
float Pi = 3.14159265f;
printf("Input the diameter of the table:");
scanf("%f", &diameter); /* Read the diameter from
the keyboard */
radius = diameter/2.0f; /* Calculate the radius
*/
circumference = 2.0f*Pi*radius; /* Calculate the
circumference */
area = Pi*radius*radius; /* Calculate the area */
printf("\nThe circumference is %.2f", circumference);
printf("nThe area is %.2f\n", area);
}
Here’s some typical output from this example:
======================================================
Input the diameter of the table: 6
The circumference is 18.85
The area is 28.27
======================================================
HOW IT WORKS
Up to the first printf() the program looks much the same as those you’ve seen before:
float radius = 0.0f; /* The radius of the table
*/
float diameter = 0.0f; /* The diameter of the
table */
float circumference = 0.0f; /* The circumference of the
table */
float area = 0.0f; /* The area of a circle */
float Pi = 3.14159265f;
You declare and initialize five variables, where Pi has its usual value. Note how all the initial values have an f at the end because you’re initializing values of type float. Without the f the values would be of type double. They would still work here, but you would be introducing some unnecessary conversion that the compiler would have to arrange, from type double to type float.
The following statement outputs a prompt for input from the keyboard:
printf("Input the diameter of the table:");
The next statement deals with reading the value for the diameter of the table. You use a new standard library function, the scanf()function, to do this:
scanf("%f", &diameter); /* Read the diameter from the
keyboard */
The scanf() function is another function that requires the stdio.h header file to be included. This function handles input from the keyboard. In effect it takes what you enter through the keyboard and interprets it as specified by the first argument, which is a control string between double quotes. In this case the control string is "%f" because you’re reading a value of type float. It stores the result in the variable specified by the second argument, diameter in this instance. The first argument is a control string similar to what you’ve used with the printf() function, except that here it controls input rather than output.
You’ve undoubtedly noticed something new here: the & preceding the variable name diameter. This is called the address of operator, and it’s needed to allow the scanf() function to store the value that is read in your variable, diameter. The reason for this is bound up with the way argument values are passed to a function. For the moment, I won’t go into a more detailed explanation of this; you’ll see more on this in Chapter 11. The only thing to remember is to use the address of operator (the & sign) before a variable when you’re using the scanf()function, and not to use it when you use the printf() function.
You’ll see a lot more on how scanf() works later in the book, but for now the basic set of format specifiers you can use for reading data of various types are as follows:
To read a value of type short %hd
To read a value of type int %d
To read a value of type long %ld
To read a value of type float %f or %e
To read a value of type double %lf or %le
In the %ld and %lf format specifiers, l is a lowercase L. Don’t forget, you must always prefix the name of the variable that’s receiving the input value with &. Also, if you use the wrong format specifier—if you read a value into a variable of type float with %d, for instance—the data value in your variable won’t be correct, but you’ll get no indication that a junk value has been stored.
Next, you have three statements that calculate the results you’re interested in:
radius = diameter/2.0f; /* Calculate the
radius */
circumference = 2.0f*Pi*radius; /* Calculate the
circumference */
area = Pi*radius*radius; /* Calculate the area */
The first statement calculates the radius as half of the value of the diameter that was entered. The second statement computes the circumference of the table, using the value that was calculated for the radius. The third statement calculates the area. Note that if you forget the f in 2.0f, you’ll probably get a warning message from your compiler. This is because without the f, the constant is of type double, and you would be mixing different types in the same expression. You’ll see more about this later.
The next two statements output the values you’ve calculated:
printf("\nThe circumference is %.2f", circumference);
printf("\nThe area is %.2f\n", area);
These two printf() statements output the values of the variables circumference and area using the format specifier %.2f. As you’ve already seen, in both statements the format control string contains text to be displayed, as well as a format specifier for the variable to be output. The format specification outputs the values with two decimal places after the point. The default field width will be sufficient in each case to accommodate the value that is to be displayed.
Of course, you can run this program and enter whatever values you want for the diameter. You could experiment with different forms of floating-point input here, and you could try entering something like 1E1f, for example.
This article is excerpted from Beginning C by Ivor Horton (Apress, 2004; ISBN 1590592530). Check it out at your favorite bookstore today. Buy this book now. |
Next: Defining Constants >>
More Code Examples Articles
More By Apress Publishing