Verifying Cost of Cylindrical Containers Production

  • Context: C/C++ 
  • Thread starter Thread starter 7longhorn
  • Start date Start date
  • Tags Tags
    Cylindrical
Click For Summary

Discussion Overview

The discussion revolves around verifying a programming assignment related to calculating the cost of producing open-top cylindrical containers. Participants explore the implementation details, accuracy of calculations, and potential improvements in the code. The scope includes technical explanations, programming practices, and considerations of numerical accuracy.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant confirms the code's functionality but suggests a more structured approach might be beneficial.
  • Another participant questions the choice of input units, noting the awkwardness of entering dimensions in inches while calculating costs in square centimeters.
  • Concerns are raised about the precision of the constant pi, with suggestions to use a more accurate representation or the constant M_PI from the library.
  • Some participants argue about the significance of rounding errors in calculations, with one providing a detailed analysis of potential cost implications due to inaccuracies.
  • There is a discussion on the representation of floating-point numbers in computers, with references to the IEEE standard and the implications for accuracy in programming.
  • One participant acknowledges a misunderstanding regarding C and C++ standards and the automatic rounding behavior of the language.

Areas of Agreement / Disagreement

Participants express differing views on the importance of numerical accuracy and the implications of using different representations of pi. There is no consensus on the best approach to handle the precision of calculations or the input/output units.

Contextual Notes

Limitations include potential misunderstandings about floating-point representation and the significance of rounding errors in financial calculations. The discussion also highlights the need for clarity in assignment requirements regarding unit conversions.

7longhorn
Messages
5
Reaction score
0
Hi, could some one please verify that I successfully completed the objective of my programming homework? This is my first assignment and I'm just being extra cautious that I did everything right.

Assignment

A manufacturer wishes to determine the cost of producing an open-top cylindrical container. The surface area of the container is the sum of the area of the circular base plus the area of the outside (the circumference of the base times the height). Write a program to take the radius of the base, the height of the container, the cost per square centimeter of the material, and the number of containers to be produced. Calculate the cost of each container and the total cost of producing all the containers.

Instructor's Notes:
You must ask for the user to enter the radius and base measurements in INCHES.

So the user provides measurements in inches but the program must then convert them into centimeters. Here is my code:

Code:
#include <iostream>

using namespace std;

int main()
{
    double radius;
    double height;
    double cost;
    int nContainers;
    double SA;
    double costContainer;
    double costAll;
    float pi = 3.14159265;
    
    cout << "Enter the radius of the base (in inches): ";
    cin >> radius;
    cout << "Enter the height of the container (in inches): ";
    cin >> height;
    cout << "Enter the cost of each container per square centimeter: $";
    cin >> cost;
    cout << "Enter the number of containers to be produced: ";
    cin >> nContainers;
	
    double Radius = radius * 2.54;
    double Height = height * 2.54;
    SA = pi * Radius * Radius + 2 * pi * Radius * Height;
    costContainer = SA * cost;
    costAll = costContainer * nContainers;
	
    cout << nContainers << " container(s) at $" << cost << " per square centimeter will cost $" << costContainer << " each." << endl;
    cout << "The grand total for " << nContainers << " containers is $" << costAll << "." << endl;
    return 0;
}

Thanks!
 
Technology news on Phys.org
Seems fine. I would probably have tried to make it more structured but because it is such a simple example, I don't think it matters.
 
I have one question and one "warning".

Why does the user input values in inches, but then cost in $/cm? Was that your choice, or might that be a mistake? Seems quite awkward.

You define pi as 3.14159265, but on a standard compiler, float stores the first 6 digits. 3.14159265 will become 3.141592, which is wrong because the 6 should round up to make the 2 a 3. Try "float pi = 3.141593;" instead.

Other than those slight things, this program is very solid for being your first assignment. Good job! Now all you need is comments.
 
Last edited:
Sane said:
You define pi as 3.14159265, but on a standard compiler, float stores the first 6 digits. 3.14159265 will become 3.141592, which is wrong because the 6 should round up to make the 2 a 3. Try "float pi = 3.141593;" instead.
What difference does it make, neither is accurate.
 
whatta said:
What difference does it make, neither is accurate.

There's no sense in being less accurate than you have to. :confused:
 
Sane said:
There's no sense in being less accurate than you have to. :confused:
Well, for the sake of an argument, let's see: error is (3.141593 - 3.141592) (Radius * Radius + 2 * Radius * Height); let's have Radius = Height for the sake of simplicity, so the above expression turns into 0.000003 * Radius * Radius, right?

Now, let's take some real world price example, like . From here, we want to know how big our cylinder has to be so that the above error would be of any significance, the equation is: 0.000003 * Radius * Radius = ($0.01 / $10.77) * 2.7870912 sq. m., which yields Radius = sqrt( ((0.01 / 10.77) * 2.7870912) / 0.000003 ) ~ 29.37 meters.

In other words, you will have less than 1 cent of error, trying to bubblewrap anything less than 60 meters in diameter.
 
Last edited by a moderator:
The user is supposed to enter dimensions in inches (per my instructor) but the program description says I need to calculate the cost per square centimeter. So unless my instructor wants us to change everything to inches and ignore that part of the description, it's just going to be awkward.

So that is why I converted from IN to CM using 2.54 cm per inch.

And thanks for the float tip.
 
whatta said:
What difference does it make, neither is accurate.

Use the constant M_PI from the <math> include file.

Then you get the best accuracy possible on the hardware you are running on, no chance of making a typo, and no futile discussions about the best way round decimal numbers before the compiler converts them to binary, and whether accuracy matters or not.

Re the "typos" thing, I once was debugging a program and I used the value of pi as one of the input quantities in the test data, because it made the answer come to a simple number to check.

Problem was, the number in my input file was 3.41459 not 3.14159. It took me three days solid work to find out there was nothing wrong with the program after all. :mad:

BTW M_PI is a double constant, not a float, so assign it to a const double variable if you don't want to use the name M_PI everywhere in your code. There's no sense in truncating it to a float, without a good reason.
 
Last edited:
Sane said:
You define pi as 3.14159265, but on a standard compiler, float stores the first 6 digits. 3.14159265 will become 3.141592, which is wrong because the 6 should round up to make the 2 a 3. Try "float pi = 3.141593;" instead.

This is wrong on at least two counts.

First, almost all computers these days use the IEEE floating point standard. Floats and doubles are represented in base 2, not base 10. The computer does not store 3.141592653598793 in a float as "3.141592", or even "3.141593". It stores it in a binary representation.

Second, the rules of C and C++ dictate that constant expression first be interpreted as a double and then demoted to a float. The demotion process involves rounding the double-precision number to the closest possible single-precision representation.

The best advice is simply

AlephZero said:
Use the constant M_PI from the <math> include file.

Then you get the best accuracy possible on the hardware you are running on, no chance of making a typo, and no futile discussions about the best way round decimal numbers before the compiler converts them to binary, and whether accuracy matters or not.
 
  • #10
whatta said:
In other words, you will have less than 1 cent of error, trying to bubblewrap anything less than 60 meters in diameter.

That's a nice example of faulty error analysis.

Suppose you output costs to the nearest cent. If the correct price (using a high-accuracy value of pi) was $0.494999 and the inaccurate price was $0.495001, then the price that was output would be $0.49 not $0.50 - i.e. a 1 cent error compared with the correct output.

Imagine I'm your boss, and because if this mistake the company sold 1,000,000 of these gizmos at the wrong price.

You say the difference doesn't matter? OK, I'll make up the difference by cutting your salary by $10,000 next year. Deal? :rolleyes:
 
  • #11
Edit :
You know you're too old... when? When you treat everything as it was back in the (good old) days, when we used C. I forgot we're talking about C++ standards here. Apolagies D H.

Another thing that I didn't realize is that C will automatically round for you anyways.​

D H said:
This is wrong on at least two counts.

First, almost all computers these days use the IEEE floating point standard. Floats and doubles are represented in base 2, not base 10. The computer does not store 3.141592653598793 in a float as "3.141592", or even "3.141593". It stores it in a binary representation.

ISO 9899 and IEC 60559 are both still standard according to our favourite publisher, O'REILLY.

Code:
Type           Storage size     Precision
=========================================
float          4 bytes          6 digits[/color]
double         8 bytes          15 digits
long double    10 bytes         19 digits
 
Last edited:
  • #12
Sane said:
Edit :
You know you're too old... when? When you treat everything as it was back in the (good old) days, when we used C. I forgot we're talking about C++ standards here.​

There is no difference between C and C++ regarding the representation of floating point numbers. Both mandate the IEEE floating point standard, IEEE 754, aka IEC 60559.


ISO 9899 and IEC 60559 are both still standard according to our favourite publisher, O'REILLY.

Code:
Type           Storage size     Precision
=========================================
float          4 bytes          6 digits[/color]
double         8 bytes          15 digits
long double    10 bytes         19 digits

Tthose precision numbers are wrong. First, they imply a decimal representation. IEC 60559 / IEE 754 is most definitely binary. http://en.wikipedia.org/wiki/IEEE_floating-point_standard" .

Second, they are just wrong.

Floats provide 23 bits mantissas plus one implied bit for normalized numbers. This equates to about 6.9 decimal digits of precision. Doubles provide 52+1 bits, or about 15.7 decimal digits.
 
Last edited by a moderator:
  • #13
Are you sure you aren't overcrediting your sources? I've got these facts from O'REILLY, which is a highly credible source for programming. Plus if you print out the constant FLT_DIG from float.h you get 6.

Code:
#include <stdio.h>
#include <float.h>

int main(  ) {
    
    float pi_1 = 3.1415926535;
    float pi_2 = 3.141593;
    
    printf( "%f\n", pi_1 );
    printf( "%f\n", pi_2 );
    printf( "Digits: %i\n", FLT_DIG );

    return 0;
    
}

Code:
3.141593
3.141593
Digits: 6

Furthermore, here's some reading material from O'REILLY:

A floating-point value can be stored only with a limited precision, which is determined by the binary format used to represent it and the amount of memory used to store it. The precision is expressed as a number of significant digits. For example, a "precision of six decimal digits" or "six-digit precision" means that the type's binary representation is precise enough to store a real number of six decimal digits, so that its conversion back into a six-digit decimal number yields the original six digits. The position of the decimal point does not matter, and leading and trailing zeros are not counted on the six digits. The numbers 123,456,000 and 0.00123456 can both be stored in a type with six-digit precision.
 
Last edited:
  • #14
Sane said:
Are you sure you aren't overcrediting your sources?

Did you read your source?

For example, a "precision of six decimal digits" or "six-digit precision" means that the type's binary representation is precise enough to store a real number of six decimal digits, so that its conversion back into a six-digit decimal number yields the original six digits.

Here are some more on-line references.
C standard, draft (2005) http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf"
Appendix F covers on IEC 60559.

"What Every Computer Scientist Should Know About Floating-Point Arithmetic" http://docs.sun.com/app/docs/doc/800-7895/6hos0aou4?a=view" Re, your code.
  • Print the difference your two representations of [itex]\pi[/itex].
  • Print FLT_RADIX, #defined in <float.h>. This is the basis of the floating point representation: [itex]n = \text{mantissa}*b^{\text{exponent}}[/itex]. A neat trick unique to base 2 is that any non-zero number can be written [itex](1+\text{fraction})*2^{\text{exponent}}[/itex]. The one is always there. You can get an extra bit of precision in base 2. (These are what IEEE 754 calls 'normalized numbers'.)
  • Print FLT_EPSILON, also #defined in <float.h>. This is the smallest positive number that, when added to 1.0, yields a number different from 1.0.

Code:
#include <stdio.h>
#include <float.h>

int main() {
   float pi_1 = 3.1415926535F;
   float pi_2 = 3.141593F;
   float pi_diff  = pi_2 - pi_1;

   printf ("%f - %f = %g\n", pi_1, pi_2, pi_diff);
   printf ("FLT_RADIX   = %d\n", FLT_RADIX);
   printf ("FLT_EPSILON = %g\n", FLT_EPSILON);

   return 0;
}

Here is what I get:

Code:
3.141593 - 3.141593 = 2.38419e-07
FLT_RADIX   = 2
FLT_EPSILON = 1.19209e-07
 
Last edited by a moderator:
  • #15
Okay. It was the "real number of six decimal digits" that threw me off. Thanks for the information D H.
 

Similar threads

  • · Replies 23 ·
Replies
23
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 3 ·
Replies
3
Views
4K
  • · Replies 9 ·
Replies
9
Views
4K
  • · Replies 15 ·
Replies
15
Views
4K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 10 ·
Replies
10
Views
3K
Replies
1
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 6 ·
Replies
6
Views
2K