here's a good one

Visual studio 9 c++ - double rounding conundrum:
Going back through my c++ text, simple coding exercise (algebra): given a surface area, generate a box of maximum length and volume. I output the dimensions in generic units L x W giving x units of volume. However the results are off in the decimal range. I'll provide the progy, and a test progy that verifies the dimension are correct.

The main program:


Running this with "1234" input results in 35.129 in length and 35.128 in width with a square cutout of 5.856 and an volume of 7226.304.
The volume should be 7226.371 (if you take the raw variable output and calculate volume it will produce correct results).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Included header file(s)
#include <iostream>
#include <iomanip>
#include <fstream>

	// Namespace declaration(s)
using namespace std;

	//Global named constants
//None

	// Function prototype(s)
void	initialize (bool& isDone, double& area, double& len, double& wdth,
					double& vol, double& maxVol, double& sqrSide, ofstream& outFile);
double	calcMaxVol (double len, double wdth, double& sqrSide);

	// Begin main function
int main ()
{
		// Variable declaration(s)
	bool		done;										// Loop control variables
	char		indicator [4] = {'|', '/', '-', '\\'};
	double		area, length, width, volume,				// Calculation variables
				maximumVol, squareSide;
	static int	x = 0;
	ofstream	outDat;

		// Initialize variables
	initialize (done, area, length, width, volume, maximumVol, squareSide, outDat);

		// Format output
	cout << fixed << showpoint << setprecision (3);
	outDat << fixed << showpoint << setprecision (3);

		// Main code including any user prompts
	cout << "Program to determine an open box of maximum length and volume"
		 << " for a given area." << endl
		 << "Please enter the area of the flat material: ";
	cin >> area;
	cout << endl << endl << "Processing...";

		// Calculate beginning dimensions
	width = area / length;
		
		// Loop to calculate results
	while (!done)
	{
		volume = calcMaxVol (length, width, squareSide);
		if (maximumVol <= volume)
		{
			maximumVol = volume;
			length += 0.001;
			width = area / length;
		}
		else
			done = true;

			// Update user screen
		cout << indicator [x] << '\b';
		x++;
		if (x == 4)
			x = 0;
		
			// Update log file
		outDat.seekp (0);
		outDat << "Suface area entered: " << area << endl
			   << "The dimensions of the flat material: " << length << " units x "
			   << width << " units" << endl
			   << "The length of the sides of the square cutout are: " << squareSide
			   << " units" << endl
			   << "This creates a box of: " << length * width * squareSide
			   << " units of volume." << endl;
	}

		// Output results
	cout << "Done!" << endl << endl;
	cout << "Surface area entered: " << area << endl
		 << "The dimensions of the flat material: " << length << " units x "
		 << width << " units" << endl
		 << "The length of sides of the square cutout are: " << squareSide 
		 << " units" << endl
		 << "This creates a box of: " << length * width * squareSide 
		 << " units of volume." << endl;

		// Close log
	outDat.close ();

	return 0;
}

	// Function definitions
void initialize (bool& isDone, double& area, double& len, double& wdth, double& vol,
				 double& maxVol, double& sqrSide, ofstream& outFile)
{
		// Assign variables default values
	isDone = false;
	area = 0;
	len = 0.001;
	wdth = 0;
	vol = 0;
	maxVol = 0;
	sqrSide = 0;
	outFile.open ("c:\\Temp\\vars.txt");
} // end initialize

double	calcMaxVol (double len, double wdth, double& sqrSide)
{
		// declare and initialize local variables
	bool		isMaxVol = false;
	double		boxVol = 0, maxVol = 0, tmpSqrSide = 0, tempLen, tempWdth;
		
			// Function code
		// initialize variables
	tempLen = len;
	tempWdth = wdth;

		// Loop to determine max volume given the current dimensions
	while (!isMaxVol)
	{
		tempLen = len -(2 * tmpSqrSide);					// Update length size
		tempWdth = wdth - (2 * tmpSqrSide);					// Update width size
		boxVol = tempLen * tempWdth * tmpSqrSide;			// Calculate volume
		if (maxVol <= boxVol)								// Check for max volume
		{
			maxVol = boxVol;
			tmpSqrSide += 0.001;
		}
		else
			isMaxVol = true;
	}
		
	sqrSide = tmpSqrSide;
	return	maxVol;
} // end calcMaxVol 


Here's a test program to calculate the variable output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <iomanip>

using namespace std;

int main ()
{
	double	num1, num2, num3;
	
	cout << "please enter some numbers: ";
	cin >> num1 >> num2 >> num3;
	cout << "your numbers mutiplied together: ";
	cout << fixed << showpoint << setprecision (3);
	cout << num1 * num2 * num3 << endl << endl;

	return 0;
}

I input the numbers from the previous program and the math is good.
Any ideas as to why I'm getting wrong precision results?
Last edited on
Most floating point numbers don't have precision representation in float or double types because there aren't enough bits. Google "What every computer scientist should know about floating point arithmetic" and read the Goldberg paper. After your head stops spinning, either accept the inaccuracy as roundoff error or perform all math in the integer domain and convert to double at output step only.
lols, I'll give it a read, thanks!
Topic archived. No new replies allowed.