Doubles are giving me problems

Oct 22, 2009 at 4:43am
Ok so, first of all i made a double = 0.05, but when running the debugger it shows up as 0.04999. I know this has something to do with how doubles store but its causing problems for me. Anyway, in the code I'm trying to get only the right hand side(rhs) of the double variable jdn's decimal point. So in the code example I'm only trying to get .05. But rhs isn't always going to be the same and can have up to 0.00005 <- that fifth one there(can't remember what its called - hundred thousandth?). I have constant numbers right now for the sake of testing this. Now the counter goes through starting at 0.1, to make sure everything after the decimal point is 0. It goes through fine until it gets to 0.0002 - 0.0001 and then rhs = 9.99998e-005.
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
#include <cmath>
#include <ctime>
#include <iostream>
using namespace std;

int main()
{
	double jdn = 2454115.05;
	double lhs = floor(jdn);
	double rhs = jdn - lhs;
	double counter = 0.1;
	if( rhs != 0.0 )
		while( (rhs != 0.000001) || (counter != 0.00001) )
		{
			if( (rhs - counter) <= 0 )
			{
				counter *= 0.1;
				//cout << "rhs = " << rhs << endl;
			}
			else
			{
				rhs -= counter;
				cout << "rhs = " << rhs << endl;
			}
		}
		cout << "ok" << endl;


	return 0;
}

Results:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
rhs = 0.04
rhs = 0.03
rhs = 0.02
rhs = 0.01
rhs = 0.009
rhs = 0.008
rhs = 0.007
rhs = 0.006
rhs = 0.005
rhs = 0.004
rhs = 0.003
rhs = 0.002
rhs = 0.001
rhs = 0.0009
rhs = 0.0008
rhs = 0.0007
rhs = 0.0006
rhs = 0.0005
rhs = 0.0004
rhs = 0.0003
rhs = 0.0002
rhs = 9.99998e-005


Help me plz -_-'
Oct 22, 2009 at 6:16am
Go look up "modf()"; I think it does what you are trying to do.
Oct 22, 2009 at 6:29am
modf still returns the 0.05 as 0.049999999813735485. The main problem is when counter gets to 0.0001 and then tries to go to 0.00001 it becomes 1.0000000000000004e-005.
Oct 22, 2009 at 12:41pm
If you want to determine fractional part of a number then use modf, as firedraco said.

You must understand that doubles are not precise. 2454115.05 is not even representable in a double precision floating-point format. Variable 'jdn' is actually set to the nearest representable number, that is 2454115.049999999813735485076904296875.
Oct 22, 2009 at 1:12pm
Ok then, why does jdn and counter turn into whole numbers with e-005 at the end of them?
Oct 22, 2009 at 1:30pm
It is printing them out in scientific notation.
Oct 22, 2009 at 1:44pm
ya how do i stop it from doing that cuz the loop never stops, and it should when rhs = 0.0 or counter = 0.00001
Oct 22, 2009 at 1:51pm
I'm not sure if I understood your question correctly, but anyway
9.99998e-005
is a number which value is represented in a scientific notation. It means
9.99998 * 10^-5
what is a little less than
0.0001
As you can see, calculations are correct.

If you would like to see 0.0001 rather than 9.99998e-005 then you must configure the stream appropriately. By default, if the given value is small enough, it is printed in a scientific notation because otherwise it would be very long (or zero would need to be printed). You can force a fixed notation, for example by doing something similar to:

1
2
cout.setf(ios::fixed, ios::floatfield);
cout.precision(4);


EDIT: I'm slow. Anyway, never use == or != with floats or doubles.
Last edited on Oct 22, 2009 at 1:53pm
Oct 22, 2009 at 4:20pm
Ok problem solved just had to change the condition of the while loop so that it would exit. Thanks all.
Topic archived. No new replies allowed.