Rounding Error

I am writing a program for my CS class that calculates miles driven, fuel used, and miles per gallon rate in a car as well as kms driven, liters used, and liters per 100kms.

I have been using fixed << setprecision to correctly round the right amount of trailing digits, however one line outputs incorrect rounding and I don't understand why?

Without posting all of my code...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
	double startMileage;
	double endMileage;
	double startFuel;
	double endFuel;
	double consumption;
	const double MILE = 1.609;
	const double GAL = 3.785;
	double km;
	double l;
	double kmconsumption;
	...
	...	
	...
	l = ((startFuel - endFuel) * GAL);
	cout << fixed << setprecision(2) << "Fuel used: " << l << " liters.\n";


Outputs 64.34 liters instead of the correct number 64.35 liters.

I can post the rest of the code if necessary

Edited to add: FYI: I am required by the assignment to use const for my conversions which is why it is set up like that.
Last edited on
It may have been loosely rounded earlier because floating-point numbers are not stored the same as integers and are not anywhere near as accurate or it could be something wrong with your calculations could you post more code please and show us the formula you are supposed to be using for the correct result.

p.s. setprecision does not round it. It just displays that many digits. If you wish to round use the round function in the cmath header.
http://www.cplusplus.com/reference/cmath/
http://www.cplusplus.com/reference/cmath/round/
Last edited on
Thanks for your quick response. Here is the complete code:

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
#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
	double startMileage;
	double endMileage;
	double startFuel;
	double endFuel;
	double consumption;
	const double MILE = 1.609;
	const double GAL = 3.785;
	double km;
	double l;
	double kmconsumption;

	cout << "Enter starting mileage: ";
	cin >> startMileage;
	cout << "Enter ending mileage: ";
	cin >> endMileage;
	cout << "Enter fuel at start in Gallons: ";
	cin >> startFuel;
	cout << "Enter fuel at end in Gallons: ";
	cin >> endFuel;
	cout << "\nNumber of miles traveled: " << (endMileage - startMileage) << " miles.\n";
	cout << fixed << setprecision(2) << "Fuel used: " << (startFuel - endFuel) << " gallons.\n";
	consumption = ((endMileage - startMileage) / (startFuel - endFuel));
	cout << fixed << setprecision(2) << "Miles per gallon of fuel: " << consumption << ".\n\n";
	km = ((endMileage - startMileage) * (MILE / 1));
	cout << fixed << setprecision(2) << "Number of kilometers traveled: " << km << "kms.\n";
	l = ((startFuel - endFuel) * GAL);
	cout << fixed << setprecision(2) << "Fuel used: " << l << " liters.\n";
	kmconsumption = (235.214 / consumption);
	cout << fixed << setprecision(2) << "Liters per 100kms: " << kmconsumption << ".\n";
}
Line 30 why are you dividing by 1?? Anything divided by 1 is equal to the starting value.

Also what are the values you are inputting? I would just assume that it is really like 64.345.... and isn't rounding up to 64.35.
As for line 30, you're right. I just need to multiple by MILE (1.609) and there's no need to divide by 1. I pulled a formula off a website and just blindly typed it in without thinking. The division by 1 was necessary for demonstrating your "work" if you were working it out on paper.

The inputs are:
Starting mileage: 300
Ending mileage: 650.45
Starting fuel in Gallons: 19
Ending fuel in Gallons: 2

You are correct. I am writing from work so I don't have access to my program, but I believe the value is 64.345 and it shows 64.34 instead of 64.35.
You may want to create a function to round it up manually then.

1
2
3
4
5
6
7
double roundHundreths( const double x ) 
{
	double result = x * 100.0 + 0.5; //moving number 2 places right and trying to round
	result = static_cast<int>( result ); //flooring
	result /= 100.0; //moving number 2 places left
    return( result );
}


example of what code does:

ex 1) 64.345
step 1: result = 64.345 * 100 + .5 = 6434.5 + .5 = 6435.0
step 2: result = 6435
step 3: result = 6435 / 100 = 64.35

ex 2) 64.344
step 1: result = 64.344 * 100 + .5 = 6434.4 + .5 = 6434.9
step 2: result = 6434
step 3: result = 6434 / 100 = 64.34
Unfortunately, my instructor specified that we are not to add any value to our results to force the rounding to happen.

I'm confused, because I am pretty sure that some of the other resulting values are rounding appropriately, but this particular value is not?! I am still at work so I don't have access to my program to confirm. Is this one having difficulty because the difference between rounding and not rounding is 0.001?
Well honestly setprecision isn't even meant for rounding it is meant for displaying a set amount of decimal digits.

Also I was not adding stuff to force a round. I was rounding it manually. If you really want to round you can use the round function from the cmath header.

Also doubles are not stored the same as integers so 64.345 could be stored as 64.3449999999999999999999999999999
Yea, I ran your suggestion by my instructor and he again repeated that we are not to add anything to the values. He suggested that what I should do instead is to
test for the specific case and round that up. Do that by checking to see if the value is exactly divisible by 0.005. Do that using the mod operation.
I am not familiar with what he is speaking of at all?
The mod operation is % is for integers not doubles so I'm not sure what he is talking. Basically it divides by a given value and returns the remainder.

Example:
10 % 3 = 1 because 3 can go into 10 3 times which is 9 so it has a remainder of 1.

Arithmetic operators ( +, -, *, /, % )
The five arithmetical operations supported by C++ are:

operator description
+ addition
- subtraction
* multiplication
/ division
% modulo

Operations of addition, subtraction, multiplication and division correspond literally to their respective mathematical operators. The last one, modulo operator, represented by a percentage sign (%), gives the remainder of a division of two values. For example:


x = 11 % 3;


results in variable x containing the value 2, since dividing 11 by 3 results in 3, with a remainder of 2.

http://www.cplusplus.com/doc/tutorial/operators/

he could be talking about the fmod function though maybe?

http://www.cplusplus.com/reference/cmath/fmod/?kw=fmod

round that up ... if the value is exactly divisible by 0.005

Honestly though I find that to be a pretty bad idea because what if it was 64.346 should that not round up also?

Also I am a bit confused when you say you can not add anything to the values when I mentioned but if you use modulus you can then round up?
Isn't rounding up adding to the value like I did? Also you could just call the function when outputting and it doesn't modify the value since not passing by reference.

I agree, I also don't understand what he is getting at at all.
Topic archived. No new replies allowed.