|
From: jody <jod...@gm...> - 2008-05-06 11:33:37
|
Hi
I'm using valgrind-3.2.1 on fedora 6.
I have encounter a situation where computations with doubles
give different result when the application is run normally or under valgrind.
Here is a very simple application showing the problem, vgt.c:
#include <stdio.h>
#include <math.h>
int main(int argc, char *argv) {
double a;
double b;
double c;
FILE *f = fopen("num.dat", "rb");
fread(&a, sizeof(double), 1, f);
fread(&b, sizeof(double), 1, f);
fread(&c, sizeof(double), 1, f);
fclose(f);
printf("a:%.20f, b:%.20f, c:%.20f\n", a,b,c);
printf("a-b:%.20f, (a-b)/c:%.20f\n", a-b,(a-b)/c);
double d = (a-b)/c;
printf("%.20f\n", floor(d));
return 0;
}
Here is the hexdump of the data file num.dat:
[jody]:~/progs/neander/import:$hexdump -C num.dat
00000000 a9 9a fe ff ff ff 48 40 00 00 00 00 00 00 2e c0 |......H@........|
00000010 6b 55 10 11 11 11 a1 3f |kU.....?|
00000018
The normal output:
[jody]:~/progs/neander/import:$./vgt
a:49.99999999935000261075, b:-15.00000000000000000000, c:0.03333333333300000229
a-b:64.99999999934999550533, (a-b)/c:1950.00000000000000000000
1950.00000000000000000000
Output under valgrind:
[jody]:~/progs/neander/import:$valgrind --tool=memcheck ./vgt
==23277== Memcheck, a memory error detector.
==23277== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==23277== Using LibVEX rev 1658, a library for dynamic binary translation.
==23277== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==23277== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==23277== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==23277== For more details, rerun with: -v
==23277==
a:49.99999999935000261075, b:-15.00000000000000000000, c:0.03333333333300000229
a-b:64.99999999934999550533, (a-b)/c:1949.99999999999977262632
1949.00000000000000000000
==23277==
==23277== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 1)
==23277== malloc/free: in use at exit: 0 bytes in 0 blocks.
==23277== malloc/free: 1 allocs, 1 frees, 352 bytes allocated.
==23277== For counts of detected errors, rerun with: -v
==23277== All heap blocks were freed -- no leaks are possible.
It is important that both calculations (normal & valgrind) are the same -
with the faulty calculation my real program never gets to the point i am
interested in.
Is this a bug or did i overlook something?
Thanks
jody
|
|
From: Julian S. <js...@ac...> - 2008-05-06 11:42:20
|
On Tuesday 06 May 2008 13:33, jody wrote: > Hi > I'm using valgrind-3.2.1 on fedora 6. > > I have encounter a situation where computations with doubles > give different result when the application is run normally or under > valgrind. Yes. See http://www.valgrind.org/docs/manual/manual-core.html#manual-core.limits, 8th bullet point. J > > > > Here is a very simple application showing the problem, vgt.c: > > #include <stdio.h> > #include <math.h> > > > int main(int argc, char *argv) { > > > double a; > double b; > double c; > FILE *f = fopen("num.dat", "rb"); > fread(&a, sizeof(double), 1, f); > fread(&b, sizeof(double), 1, f); > fread(&c, sizeof(double), 1, f); > fclose(f); > > printf("a:%.20f, b:%.20f, c:%.20f\n", a,b,c); > printf("a-b:%.20f, (a-b)/c:%.20f\n", a-b,(a-b)/c); > double d = (a-b)/c; > printf("%.20f\n", floor(d)); > return 0; > } > > Here is the hexdump of the data file num.dat: > [jody]:~/progs/neander/import:$hexdump -C num.dat > 00000000 a9 9a fe ff ff ff 48 40 00 00 00 00 00 00 2e c0 > |......H@........| 00000010 6b 55 10 11 11 11 a1 3f > |kU.....?| 00000018 > > The normal output: > [jody]:~/progs/neander/import:$./vgt > a:49.99999999935000261075, b:-15.00000000000000000000, > c:0.03333333333300000229 a-b:64.99999999934999550533, > (a-b)/c:1950.00000000000000000000 > 1950.00000000000000000000 > > Output under valgrind: > [jody]:~/progs/neander/import:$valgrind --tool=memcheck ./vgt > ==23277== Memcheck, a memory error detector. > ==23277== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. > ==23277== Using LibVEX rev 1658, a library for dynamic binary translation. > ==23277== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. > ==23277== Using valgrind-3.2.1, a dynamic binary instrumentation framework. > ==23277== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. > ==23277== For more details, rerun with: -v > ==23277== > a:49.99999999935000261075, b:-15.00000000000000000000, > c:0.03333333333300000229 a-b:64.99999999934999550533, > (a-b)/c:1949.99999999999977262632 > 1949.00000000000000000000 > ==23277== > ==23277== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 1) > ==23277== malloc/free: in use at exit: 0 bytes in 0 blocks. > ==23277== malloc/free: 1 allocs, 1 frees, 352 bytes allocated. > ==23277== For counts of detected errors, rerun with: -v > ==23277== All heap blocks were freed -- no leaks are possible. > > > It is important that both calculations (normal & valgrind) are the same - > with the faulty calculation my real program never gets to the point i am > interested in. > > Is this a bug or did i overlook something? > > Thanks > jody > > ------------------------------------------------------------------------- > This SF.net email is sponsored by the 2008 JavaOne(SM) Conference > Don't miss this year's exciting event. There's still time to save $100. > Use priority code J8TL2D2. > http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/java >one _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users |
|
From: Michael P. <md...@tr...> - 2008-05-06 11:53:35
|
jody writes: > Hi > I'm using valgrind-3.2.1 on fedora 6. > > I have encounter a situation where computations with doubles > give different result when the application is run normally or under valgrind. > > > > Here is a very simple application showing the problem, vgt.c: Your test program behaves differently based on the implementation of "double". In particular, the 1950 result depends on the intermediate results being calculated using 80-bit floats, as is traditional on the stack of x86 FPUs. If the compiled code uses 64-bit floats, which will happen on x86-64 (and most other) machines, if you use gcc's -ffloat-store flag on x86 machines, or if you use Valgrind, it produces the 1949 result. According to http://valgrind.org/help/projects.html, the Vex library that underlies Valgrind only supports 64-bit floating-point arithmetic, so there is probably no way to get the 80-bit results within Valgrind. Michael Poole |
|
From: jody <jod...@gm...> - 2008-05-06 12:41:09
|
Thanks for the info! As i don't need 80bit precision, I guess i'll get by with some appropriate floating point tricks such as addin small values and rounding.... Jody On Tue, May 6, 2008 at 1:53 PM, Michael Poole <md...@tr...> wrote: > jody writes: > > > Hi > > I'm using valgrind-3.2.1 on fedora 6. > > > > I have encounter a situation where computations with doubles > > give different result when the application is run normally or under valgrind. > > > > > > > > Here is a very simple application showing the problem, vgt.c: > > Your test program behaves differently based on the implementation of > "double". In particular, the 1950 result depends on the intermediate > results being calculated using 80-bit floats, as is traditional on the > stack of x86 FPUs. If the compiled code uses 64-bit floats, which > will happen on x86-64 (and most other) machines, if you use gcc's > -ffloat-store flag on x86 machines, or if you use Valgrind, it > produces the 1949 result. > > According to http://valgrind.org/help/projects.html, the Vex library > that underlies Valgrind only supports 64-bit floating-point > arithmetic, so there is probably no way to get the 80-bit results > within Valgrind. > > Michael Poole > |
|
From: Dallman, J. <joh...@si...> - 2008-05-06 13:10:36
|
You'll do better to run your app with 64-bit precision throughout, even when it isn't running under valgrind. fpu_control.h has the constants and functions you'll need to do that. -- John Dallman Parasolid Porting Engineer > -----Original Message----- > From: val...@li... [mailto:valgrind- > use...@li...] On Behalf Of jody > Sent: Tuesday, May 06, 2008 1:41 PM > To: Michael Poole > Cc: val...@li... > Subject: Re: [Valgrind-users] precision problem > > Thanks for the info! > As i don't need 80bit precision, I guess i'll get by with > some appropriate floating point tricks such as addin small > values and rounding.... > > Jody > On Tue, May 6, 2008 at 1:53 PM, Michael Poole <md...@tr...> > wrote: > > jody writes: > > > > > Hi > > > I'm using valgrind-3.2.1 on fedora 6. > > > > > > I have encounter a situation where computations with doubles > > > give different result when the application is run normally or > under valgrind. > > > > > > > > > > > > Here is a very simple application showing the problem, vgt.c: > > > > Your test program behaves differently based on the implementation of > > "double". In particular, the 1950 result depends on the > intermediate > > results being calculated using 80-bit floats, as is traditional on > the > > stack of x86 FPUs. If the compiled code uses 64-bit floats, which > > will happen on x86-64 (and most other) machines, if you use gcc's > > -ffloat-store flag on x86 machines, or if you use Valgrind, it > > produces the 1949 result. > > > > According to http://valgrind.org/help/projects.html, the Vex library > > that underlies Valgrind only supports 64-bit floating-point > > arithmetic, so there is probably no way to get the 80-bit results > > within Valgrind. > > > > Michael Poole > > > > ----------------------------------------------------------------------- > -- > This SF.net email is sponsored by the 2008 JavaOne(SM) Conference > Don't miss this year's exciting event. There's still time to save $100. > Use priority code J8TL2D2. > http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/ > javaone > _______________________________________________ > Valgrind-users mailing list > Val...@li... > https://lists.sourceforge.net/lists/listinfo/valgrind-users |
|
From: Dirk S. <val...@ds...> - 2008-05-06 15:10:19
|
Hello, > As i don't need 80bit precision, I guess i'll get by with > some appropriate floating point tricks such as addin small > values and rounding.... If you want to write portable applications this is anyway required. Many floating point using applications fail mysteriously, when compiled with different compiler options, on different systems and so on, when you do not care for such things. Usually it is better to have an "if(fabs(a-b) < epsilon)" compared to an "if(a == b)". This will save you a lot of debugging trouble later on. Always remember that floating point is an approximation when writing value tests. Ciao -- http://www.dstoecker.eu/ (PGP key available) |
|
From: Nicholas N. <nj...@cs...> - 2008-05-07 07:14:50
|
On Tue, 6 May 2008, Dirk Stoecker wrote: > Usually it is better to have an "if(fabs(a-b) < epsilon)" compared to an > "if(a == b)". That is better than pure equality, but still has various pitfalls. See http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm for an excellent discussion of this topic, and a very nice implementation of FP equality. Nick |
|
From: Dirk S. <val...@ds...> - 2008-05-07 14:13:07
|
On Wed, 7 May 2008, Nicholas Nethercote wrote: >> Usually it is better to have an "if(fabs(a-b) < epsilon)" compared to an >> "if(a == b)". > > That is better than pure equality, but still has various pitfalls. See > http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm > for an excellent discussion of this topic, and a very nice implementation of > FP equality. Nice link. Directly went into my bookmarks. Actually till now I never needed anything below "Comparing with epsilon – relative error", but good to know there are possibilites. Thought if I implement these in code, I will be the only one understanding how these work. Usually not a good idea. I usually avoid comparisons with floats whenever possible and stick to integer as long as possible :-) Nowadays, where 64 bit ints are available this works fine most of the time. Ciao -- http://www.dstoecker.eu/ (PGP key available) |