Problems with multiplications of doubles and/or floats

J

John Harrison

J.K. Becker said:
Is there the slightest chance that the debugger shows wrong values but
the calculation acutally uses the right ones? (gdb/ddd)

That's entirely possible. Have you tried dumping the values out to a file?

john
 
K

Karl Heinz Buchegger

In principle you are right.
But the number the OP has posted are far to much off, that the
error can be attributed to some floating point problem.
He has a bug somewhere else.
 
J

John Harrison

J.K. Becker said:
This is the function where the error occurs. As you can see there are a
lot of calculations in it, they all work fine except the one mentioned
(which seems to be the easiest one).

Fx = un.x * dEdp;
Fy = un.y * dEdp;

This always gives the wrong results... Everything before it works and
everything after it works too (except that everything is calculated with
the wrong values for Fx and Fy).


But I guess it is too complex for a quick fix...

Maybe the function is too complex for the compiler's optimiser. Compiler
optimiser bugs aren't totally unheard of.

Have you tried changing the optimisation settings (i.e. disabling it
entirely) or spliting the function into smaller pieces.

john
 
B

Buster

J.K. Becker said:
I did a printf in the function, and it showed the same vaules as the
debugger does so I guess it is not that....

What printf did you do?

[ Fx = un.x * dEdp; ]
[ Fy = un.y * dEdp; ]

If you only checked the value of the result, I suggest you check the
value of un.x and of dEdp as well, using printf rather than the
debugger. (If it were me I'd be using "std::cerr << un.x" etc..)
 
J

J.K. Becker

Buster said:
J.K. Becker said:
I did a printf in the function, and it showed the same vaules as the
debugger does so I guess it is not that....


What printf did you do?

[ Fx = un.x * dEdp; ]
[ Fy = un.y * dEdp; ]

If you only checked the value of the result, I suggest you check the
value of un.x and of dEdp as well, using printf rather than the
debugger. (If it were me I'd be using "std::cerr << un.x" etc..)
I printf'ed (nice word!) them all, all the same..
 
J

J.K. Becker

John said:
Maybe the function is too complex for the compiler's optimiser. Compiler
optimiser bugs aren't totally unheard of.

Have you tried changing the optimisation settings (i.e. disabling it
entirely) or spliting the function into smaller pieces.

john

This part of the code is not optimized at all, but it uses libraries
(that we wrote) which have been compiled with -O .
Can that make a difference? If I have to recompile all those without
optimization, I would have to change a lot of Makefiles...

Jens
 
J

J.K. Becker

I just found out some really strange behaviour..
If I debug the whole thing now (that I use -ggdb), the debugger does not
go through the code one line to the next, but keeps jumping back and
forth a few times (hard to explain, but I hope you know what I mean).
And each time it jumps around, the value of dEdp changes. If the
debugger is past the point of the calculation, dEdp does not change
anymore, but shows the (I think) correct value (which it didn't when the
program actually calculated the stuff). Where does that come from?
Although I have not found any flags for optimization in the Makefile,
can it be that?

Does that ring any bells?

Jens
 
J

John Harrison

J.K. Becker said:
This part of the code is not optimized at all, but it uses libraries
(that we wrote) which have been compiled with -O .
Can that make a difference?

I don't see how it could, but its not something I know a great deal about.
Optimisation is normally done on a per function basis as far as I am aware.

john
 
J

J.K. Becker

Ok, after a make clean -- makeg (again) this is what happens:
dEdp gets a value in line 1, if the program continues to line 2 dEdp
changes. So the calculation is done correctly, but the value changes for
some reason. And most of the time it changes back to the right value
after line 3...

I have put the function into an older version of the program, it does
more or less the same but dEdp does not change back to the original
value after completing with line 3....

I have no idea, but I wish I would get a Euro for every time I did make,
I would be stinking rich by now!


1- dEdp = ( ( gvector.x / gvector.y ) + ( gvector.y / gvector.x ) ) / lenP;
2- Fx = un.x * dEdp;
3- Fy = un.y * dEdp;


Jens
 
B

Bill Seurer

J.K. Becker said:
////////
//////// wrong results in this calculation
////////
Fx = un.x * dEdp;
Fy = un.y * dEdp;
////////
////////
////////

Print the values of all the parts of the expressions and the results and
see if they really are what you think they are.
 
B

Buster

J.K. Becker said:
I just found out some really strange behaviour..
If I debug the whole thing now (that I use -ggdb), the debugger does not
go through the code one line to the next, but keeps jumping back and
forth a few times (hard to explain, but I hope you know what I mean). [...]
Although I have not found any flags for optimization in the Makefile,
can it be that?

Have you tried "-ggdb -O0" (no optimization)?

(That's "Minus Oh Zero" ;)
 
J

J.K. Becker

Buster said:
J.K. Becker said:
I just found out some really strange behaviour..
If I debug the whole thing now (that I use -ggdb), the debugger does
not go through the code one line to the next, but keeps jumping back
and forth a few times (hard to explain, but I hope you know what I mean).
[...]

Although I have not found any flags for optimization in the Makefile,
can it be that?


Have you tried "-ggdb -O0" (no optimization)?

(That's "Minus Oh Zero" ;)

No, I haven't, but if I give dEdp a value (e.g. dEdp=0.01;) everything
works fine...

I think I am going to go and get a piece of paper and a pen and dump the
stupid computer-simulation...... ;0)

Jens
 
J

J.K. Becker

Bill said:
Print the values of all the parts of the expressions and the results and
see if they really are what you think they are.

I (we) have realized that the error is because dEdp changes its value..
I still have no idea why, but it seems that I am getting somewhere..

Jens
 
J

John Harrison

J.K. Becker said:
Ok, after a make clean -- makeg (again) this is what happens:
dEdp gets a value in line 1, if the program continues to line 2 dEdp
changes. So the calculation is done correctly, but the value changes for
some reason. And most of the time it changes back to the right value
after line 3...

I have put the function into an older version of the program, it does
more or less the same but dEdp does not change back to the original
value after completing with line 3....

I have no idea, but I wish I would get a Euro for every time I did make,
I would be stinking rich by now!


1- dEdp = ( ( gvector.x / gvector.y ) + ( gvector.y / gvector.x ) ) / lenP;
2- Fx = un.x * dEdp;
3- Fy = un.y * dEdp;


Jens

I wonder if you are running into compiler problems because of the complexity
of the function. I'd try breaking the function into two pieces. Just a
hunch. Of course even you did this and it worked it wouldn't prove anything.

john
 
B

Bill Seurer

J.K. Becker said:
Ok, after a make clean -- makeg (again) this is what happens:
dEdp gets a value in line 1, if the program continues to line 2 dEdp
changes. So the calculation is done correctly, but the value changes for
some reason. And most of the time it changes back to the right value
after line 3...

I have put the function into an older version of the program, it does
more or less the same but dEdp does not change back to the original
value after completing with line 3....

I have no idea, but I wish I would get a Euro for every time I did make,
I would be stinking rich by now!


1- dEdp = ( ( gvector.x / gvector.y ) + ( gvector.y / gvector.x ) ) / lenP;
2- Fx = un.x * dEdp;
3- Fy = un.y * dEdp;

Try putting "volatile" on the declarations of all the things used in the
above expressions like this:
volatile float dEdp;
And see what happens.

Also, change all your "floats" to "doubles" and see what happens.
 
T

Thomas Matthews

J.K. Becker said:
Ok, after a make clean -- makeg (again) this is what happens:
dEdp gets a value in line 1, if the program continues to line 2 dEdp
changes. So the calculation is done correctly, but the value changes for
some reason. And most of the time it changes back to the right value
after line 3...

I have put the function into an older version of the program, it does
more or less the same but dEdp does not change back to the original
value after completing with line 3....

I have no idea, but I wish I would get a Euro for every time I did make,
I would be stinking rich by now!


1- dEdp = ( ( gvector.x / gvector.y ) + ( gvector.y / gvector.x ) ) / lenP;
2- Fx = un.x * dEdp;
3- Fy = un.y * dEdp;


Jens

Try declaring "dedp" as either static or volatile.
These two modifiers will help prevent variables being optimized-out.
I've seen my debugger change values of two variables when only one
has been changed (the compiler uses the same register later on..).

Also, have you considered rewriting the arithmetic to:
1. Removed fixed calculations & variables out of loops?
2. Changing multiplication to repetitive addition?

I highly suggest you use print to a debug file, with statements
like:
fprintf(debug_file, "At Line %d: dEdp == %f, un.x == %f\n",
__LINE__, dEdp, un.x);
Insert this kind of print statement after each line of calculation.
This will slow down the program, but you will get a detailed
analysis in the debug file.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
 
J

J.K. Becker

John said:
I wonder if you are running into compiler problems because of the complexity
of the function. I'd try breaking the function into two pieces. Just a
hunch. Of course even you did this and it worked it wouldn't prove anything.

john

Since you suggest it, it obviously is a possibility, but I wonder why? I
mean in the end it is just standart vector-calculation (the compiler of
course has never heard of that), but is this complex already? And if so,
wouldn't you expect the error somewhere in the for-loop for example, in
the middle of the calculations, instead of at the beginning where
everything is still simple? This is all new stuff to me, so far
everything worked fine or were stupid mistakes I made somewhere (e.g. my
alltime favorite->type collisions with double x; x=1; and such)..

Jens
 
J

J.K. Becker

Bill said:
Try putting "volatile" on the declarations of all the things used in the
above expressions like this:
volatile float dEdp;
And see what happens.

Also, change all your "floats" to "doubles" and see what happens.
Hmmm.....

Volatile seems to save my day! I must admit I have never heard of that
before and it does not make sense to me that it seems to work since I am
not optimizing anything (no -O in the Makefile) but what do I care. Now
I just have to make sure that it really works....

Thanks a lot!
Jens
 
J

J.K. Becker

Does gcc "secretly" optimize something if I do not explicitly say -O0?
No idea, never thought about that...

Jens
 
B

Buster

J.K. Becker said:
Does gcc "secretly" optimize something if I do not explicitly say -O0?
No idea, never thought about that...

No, my mistake. -O0 is the default. (From the "Options That Control
Optimization" page of gcc's Texinfo manual.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top