Home arrow C++ arrow Page 8 - First Steps in (C) Programming, continued
C++

First Steps in (C) Programming, continued


If you're a beginning programmer and want to get more deeply into programming with variables, you've come to the right place. This article, the second of three parts, is excerpted from chapter two of the book Beginning C, written by Ivor Horton (Apress, 2004; ISBN: 1590592530).

Author Info:
By: Apress Publishing
Rating: 4 stars4 stars4 stars4 stars4 stars / 22
November 23, 2005
TABLE OF CONTENTS:
  1. · First Steps in (C) Programming, continued
  2. · Variables and Memory
  3. · Integer Constants
  4. · Floating-Point Variables
  5. · More on Format Specifiers
  6. · More Complex Expressions
  7. · Defining Constants
  8. · Try It Out: The Right Types of Variables

print this article
SEARCH DEVARTICLES

First Steps in (C) Programming, continued - Try It Out: The Right Types of Variables
(Page 8 of 8 )

Here’s an example of how things can go horribly wrong if you choose an unsuitable type for your variables:

/* Program 2.11 Choosing the correct type for the job 1*/
#include <stdio.h>
void main()
{
  const float Revenue_per_150 = 4.5f;
  short JanSold = 23500;    /* Stock sold in January  */
  short FebSold = 19300;    /* Stock sold in February */
  short MarSold = 21600;    /* Stock sold in March    */
  float RevQuarter = 0.0f;  /* Sales for the quarter  */
  short QuarterSold = JanSold+FebSold+MarSold;    /* Calculate quarterly total */
 
/* Output monthly sales and total for the quarter */
  printf("\nStock sold in\n Jan: %d\n Feb: %d\n Mar: %d",
     JanSold,FebSold,MarSold);
  printf("\nTotal stock sold in first quarter: %d",QuarterSold);
 
/* Calculate the total revenue for the quarter and output it */
  RevQuarter = QuarterSold/150*Revenue_Per_150;
  printf("\nSales revenue this quarter is:$%.2f\n",RevQuarter);
}

These are fairly simple calculations, and you can see that the total stock sold in the quarter should be 64400. This is just the sum of each of the monthly totals, but if you run the program, the output you get is this:

--------------------------------------------
Stock sold in
Jan: 23500
Feb: 19300
Mar: 21600
Total stock sold in first quarter: -1136 Sales revenue this quarter is:$-31.50
--------------------------------------------

Obviously, all is not right here. It doesn’t take a genius or an accountant to tell you that adding three big, positive numbers together shouldn’t give a negative result!

HOW IT WORKS

First you define a constant that will be used in the calculation:

const Revenue_per_150 = 4.5f;

This defines the revenue obtained for every 150 items sold. There’s nothing wrong with that.

Next, you declare four variables and assign initial values to them:

short JanSold = 23500;    /* Stock sold in January  */
short FebSold = 19300;    /* Stock sold in February */
short MarSold = 21600;    /* Stock sold in March    */
float RevQuarter = 0.0f;  /* Sales for the quarter  */

The first three variables are of typeshort, which is quite adequate to store the initial value. TheRevQuartervariable is of typefloatbecause you want two decimal places for the quarterly revenue.

The next statement declares the variableQuarterSoldand stores the sum of the sales for each of the months:

short QuarterSold = JanSold+FebSold+MarSold; /* Calculate quarterly total */

Note that you’re initializing this variable with the result of an expression. This is possible only because the values of these variables are known to the compiler, so this represents what is known as a constant expression.  If any of the values in the expression were determined during execution of the program—from a calculation involving a value that was read in, for instance—then this wouldn’t compile. The compiler can only use initial values that are explicit or are produced by an expression that the compiler can evaluate.

In fact, the cause of the erroneous results is in the declaration of theQuarterSoldvariable. You’ve declared it to be of typeshortand given it the initial value of the sum of the three monthly figures. You know that their sum is 64400 and that the program outputs a negative number. The error must therefore be in this statement.

The problem arises because you’ve tried to store a number that’s too large for typeshort. If you remember, the maximum value that ashortvariable can hold is 32,767. The computer can’t interpret the value ofQuarterSold correctly and happens to give a negative result. The solution to your problem is to use a variable of typelongthat will allow you to store much larger numbers.

SOLVING THE PROBLEM

Try changing the program and running it again. You need to change only two lines in the body of the functionmain(). The new and improved program is as follows:

/* Program 2.12 Choosing the correct type for the job 2 */
#include <stdio.h>
void main()
{
  const float Revenue_Per_150 = 4.5f;
  short JanSold =23500;     /* Stock sold in January  */
  short FebSold =19300;     /* Stock sold in February */
  short MarSold =21600;     /* Stock sold in March    */
  float RevQuarter = 0.0f;  /* Sales for the quarter  */
 
long QuarterSold = JanSold+FebSold+MarSold; /* Calculate quarterly total */
 
/* Output monthly sales and total for the quarter */
  printf("Stock sold in\n Jan: %d\n Feb: %d\n Mar: %d\n",
  JanSold,FebSold,MarSold);
  printf("Total stock sold in first quarter: %ld\n",QuarterSold);
 
/* Calculate the total revenue for the quarter and output it */
  RevQuarter = QuarterSold/150*Revenue_Per_150;
  printf("Sales revenue this quarter is:$%.2f\n",RevQuarter);
}

When you run this program, the output is more satisfactory:

--------------------------------------------
Stock sold in
Jan: 23500
Feb: 19300
Mar: 21600
Total stock sold in first quarter: 64400 Sales revenue this quarter is: $1930.50
--------------------------------------------

The stock sold in the quarter is correct, and you have a reasonable result for revenue. Notice that you use%ldto output the total stock sold. This is to tell the compiler that it is to use alongconversion for the output of this value. Just to check the program, calculate the result of the revenue yourself with a calculator.

The result you should get is, in fact, $1,932. Somewhere you’ve lost a dollar and a half! Not such a great amount, but try saying that to an accountant! You need to find the lost $1.50. Consider what’s happening when you calculate the value for revenue in the program:

RevQuarter = QuarterSold/150*Revenue_Per_150;

Here you’re assigning a value toRevQuarter. The value is the result of the expression on the right of the=sign. The result of the expression will be calculated, step by step, according to the precedence rules you’ve already looked at in this chapter. Here you have quite a simple expression that’s calculated from left to right, as division and multiplication have the same priority. Let’s work through it:

QuarterSold/150is calculated as 64400/150, which should produce the result 429.333.

This is where your problem arises.QuarterSold is an integer and so the computer truncates the result of the division to an integer, ignoring the .333. This means that when the next part of the calculation is evaluated, the result will be slightly off:

429*Revenue_Per_150is calculated as 429 * 4.5 which is 1930.50.

You now know where the error has occurred, but what can you do about it? You could change all of your variables to floating-point types, but that would defeat the purpose of using integers in the first place. The numbers entered really are integers, so you’d like to store them as such. Is there an easy solution to this? In this case there is. You can rewrite the statement as follows:

RevQuarter = Revenue_Per_150*QuarterSold/150;

Now the multiplication will occur first, and because of the way arithmetic with mixed operands works, the result will be of typefloat. The compiler will automatically arrange for the integer operand to be converted to floating-point.

When you then divide by 150, that operation will execute withfloatvalues too, with150being converted to150f. The net effect is that the result will now be correct.

However, there’s more to it than that. Not only do you need to understand more about what happens with arithmetic between operands of different types, but also you need to understand how you can control conversions from one type to another. In C you have the ability to explicitly convert a value of one type to another type. This process is called casting.

..........................................................................................


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus
C++ ARTICLES

- Intel Threading Building Blocks
- Threading Building Blocks with C++
- Video Memory Programming in Text Mode
- More Tricks to Gain Speed in Programming Con...
- Easy and Efficient Programming for Contests
- Preparing For Programming Contests
- Programming Contests: Why Bother?
- Polymorphism in C++
- Overview of Virtual Functions
- Inheritance in C++
- Extending the Basic Streams in C++
- Using Stringstreams in C++
- Custom Stream Manipulation in C++
- General Stream Manipulation in C++
- Serialize Your Class into Streams in C++

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials