Prev: Static variable in template function
Next: How to reuse an existing stream with a different streambuf ?
From: AlMel on 6 Jun 2010 00:13 Dear all! I'm writing a fairly simple program interpreting an input with numbers in exponential notation. I have encountered a problem in MS VisualC++ 2008 Express Edition which is illustrated in the following code: #include <iostream> #include <string> #include <sstream> using namespace std; int main() { string s1 = "0.003 \n 0.0003 \n 0.00003 \n 0.000000000000000000000000000000000000000000000000000003"; string s2 = "3.e-3 \n 3.e-4 \n 3.e-5 \n 3.e-54"; stringstream ss1(s1), ss2(s2); double d1, d2; ss1 >> d1; ss2 >> d2; cout << d1 << " = " << "3.e-3" << " ? " << int(d1 == d2) << endl; ss1 >> d1; ss2 >> d2; cout << d1 << " = " << "3.e-4" << " ? " << int(d1 == d2) << endl; ss1 >> d1; ss2 >> d2; cout << d1 << " = " << "3.e-5" << " ? " << int(d1 == d2) << endl; ss1 >> d1; ss2 >> d2; cout << d1 << " = " << "3.e-54" << " ? " << int(d1 == d2) << endl; cin >> d1; return 0; } The output is: 0.003 = 3.e-3 ? 1 0.0003 = 3.e-4 ? 0 3e-005 = 3.e-5 ? 0 3e-054 = 3.e-54 ? 0 If I compile the same program using Mingw (GCC 4.4.0) on the same machine under the same Windows, I get the correct answers: 0.003 = 3.e-3 ? 1 0.0003 = 3.e-4 ? 1 3e-005 = 3.e-5 ? 1 3e-054 = 3.e-54 ? 1 I think the problem is in the standard library, which is hard to repair, but may be I'm wrong. Any ideas on how to get the same correct output on MS VisualC+++ 2008 Express Edition? Would be nice if someone could test the code on pro edition or on newer VisualC++ versions. Thank you in advance! With best wishes, Alex -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Lailoken on 6 Jun 2010 07:18 On Jun 6, 8:13 am, AlMel <alexander.melkoze...(a)gmail.com> wrote: > Dear all! > > I'm writing a fairly simple program interpreting an input with numbers > in exponential notation. I have encountered a problem in MS VisualC++ > 2008 Express Edition which is illustrated in the following code: Well, I think the first thing you need to read: "What Every Computer Scientist Should Know About Floating-Point Arithmetic" http://docs.sun.com/source/806-3568/ncg_goldberg.html Also, you may want to set some project settings in Visual Studio that has to do with floating point accuracy/speed (I don't recall where/ what they are, but I know they are there... although it is unlikely that these will solve your 'problem'). But the gist of it is that you cannot, *should not*, use '=' to compare floating point numbers in any application where you value correctness. Write a Equals() function to do this that takes a optional (machine) epsilon parameter to denote variance. This is the life of floating point programmers... live with it. If you need fixed point decimals perhaps consider using integer math with shifted decimals (a lot of caveats go with this one too). -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Pete Becker on 6 Jun 2010 17:13 On 2010-06-06 06:18:10 -1000, Lailoken said: > But the gist of it is that you cannot, *should not*, use '=' to > compare floating point numbers in any application where you value > correctness. Write a Equals() function to do this that takes a > optional (machine) epsilon parameter to denote variance. This is a really bad idea. The application's tolerance for roundoff errors depends on the precision of the data that it's operating on, the details of the computations that are being done on that data, and the desired results. Replacing == with nearly-equal doesn't address any of those issues. The only way to get accurate results from any computation is to understand what it's doing and what the implications are for the results. Nobody would make this sort of recommendation for integer arithmetic, despite the fact that 1/3 multiplied by 3 is 0, not 1. The reason, of course, is that you've learned how to manage the roundoff errors that occur with integer math. If you're serious about floating-point math you have to do the same thing: learn how it works. Note also that nearly-equal is not transitive, so using it will introduce a whole new set of peculiar problems. -- Pete Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The Standard C++ Library Extensions: a Tutorial and Reference (www.petebecker.com/tr1book) [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Andrew on 8 Jun 2010 02:43 On 6 June, 22:18, Lailoken <lailo...(a)gmail.com> wrote: > On Jun 6, 8:13 am, AlMel <alexander.melkoze...(a)gmail.com> wrote: > > > Dear all! > > > I'm writing a fairly simple program interpreting an input with numbers > > in exponential notation. I have encountered a problem in MS VisualC++ > > 2008 Express Edition which is illustrated in the following code: > > Well, I think the first thing you need to read: > > "What Every Computer Scientist Should Know About Floating-Point > Arithmetic"http://docs.sun.com/source/806-3568/ncg_goldberg.html > > Also, you may want to set some project settings in Visual Studio that > has to do with floating point accuracy/speed (I don't recall where/ > what they are, but I know they are there... although it is unlikely > that these will solve your 'problem'). > > But the gist of it is that you cannot, *should not*, use '=' to > compare floating point numbers in any application where you value > correctness. Write a Equals() function to do this that takes a > optional (machine) epsilon parameter to denote variance. Almost, but not quite. Knuth recommends that a relative tolerance is used. Boost has tackled this issue, which is documented at http://www.boost.org/doc/libs/1_32_0/libs/test/doc/components/test_tools/floating_point_comparison.html. Also, as Pete indicates, it is very dangerous to do these sorts of comparison in mid-calculation. I find that compare with tolerance is ok in test harnesses for testing that a complex calculation finally yields the result that is desired. Regards, Andrew Marlow -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: AlMel on 8 Jun 2010 22:27 > But the gist of it is that you cannot, *should not*, use '=' to > compare floating point numbers in any application where you value > correctness. Write a Equals() function to do this that takes a > optional (machine) epsilon parameter to denote variance. > > This is the life of floating point programmers... live with it. If you > need fixed point decimals perhaps consider using integer math with > shifted decimals (a lot of caveats go with this one too). Thank you for your help. I think that I did not formulate the problem clear enough. The problem here is not the floating-point '=' operator but rather Visual C++ standard library (in particular, the stringstream implimentation) which does not interpret "0.0003" and "3.e-4" as a same floating-point number. The resulting binary floating- point representations differ by a small quantity (epsilon). In GCC, the standard library correctly reads both notations and produces the same binary representation. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Next
|
Last
Pages: 1 2 Prev: Static variable in template function Next: How to reuse an existing stream with a different streambuf ? |