 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
baygross@gmail.com Guest
|
Posted: Sun Nov 20, 2005 5:01 pm Post subject: simple problem?? |
|
|
#include <iostream>
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1) returns
true, but for some reason this code will never output: 1 and 0.5.
I am very new to c++, and would apreciate some suggestions?
-BG
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Mon Nov 21, 2005 9:49 am Post subject: Re: simple problem?? |
|
|
[email]baygross (AT) gmail (DOT) com[/email] writes:
| Quote: | #include <iostream
|
Side note:
portably work the way you expect.
| Quote: | using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
|
The problem is with this comparison. Most floating point numbers can't
be represented accurately by computers because that would require an
infinite amount of memory. The floating point machinery of a computer
will therefore use approximate values for most floating point values.
Apparently, num2 will never reach exactly 1 (or, more accurately, the
value used by your computer to represent 1).
Using == and != on floating point values is therefore only a good idea
after careful study of the floating point machinery of the platform
the program runs on.
Often, it is good enough to consider two floating point values to be
equal if they belong to the same small interval.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alberto Ganesh Barbati Guest
|
Posted: Mon Nov 21, 2005 10:02 am Post subject: Re: simple problem?? |
|
|
[email]baygross (AT) gmail (DOT) com[/email] wrote:
| Quote: | #include
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1) returns
true, but for some reason this code will never output: 1 and 0.5.
I am very new to c++, and would apreciate some suggestions?
|
When working with floating point numbers, you always need to take
representation errors and rounding errors into account. It might well be
that num is never exactly 1, but maybe something like 1.00000001 or
...99999999. In that case num2 won't be exactly 1 and the test will fail.
In fact, the == and != tests should always be used with extreme care and
are better avoided when working with floating point numbers.
A better test is the following:
int main()
{
const double epsilon = 0.0001;
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (abs(num2 - 1) <= epsilon)
cout << num << endl;
}
return(0);
}
You can play with the value of epsilon to see what changes.
For your reference, integer operations, in absence of overflows, are
always exact. So if you multiply everything by ten the code will produce
the correct output:
int main()
{
int num, num2;
for (num=-300; num<=300; num+=1)
{
num2=-2*(num*num)+3*(num);
if (num2==10)
cout << num / 10.0 << endl;
}
return(0);
}
HTH,
Ganesh
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Richter Guest
|
Posted: Mon Nov 21, 2005 10:30 am Post subject: Re: simple problem?? |
|
|
[email]baygross (AT) gmail (DOT) com[/email] wrote:
| Quote: | int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
|
0.1 is not exactly representable as double on most platforms. Don't do
that, errors will accumulate.
| Quote: | {
num2=-2*(num*num)+3*(num);
if (num2==1)
|
Don't compare floating point values for equality.
| Quote: | cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1) returns
true, but for some reason this code will never output: 1 and 0.5.
I am very new to c++, and would apreciate some suggestions?
|
Change the loop above to use an "int" as control variable, let the loop
run from -300 to 300, increment by one. Compute num from this variable.
Instead of comparing for equality, you could a) use an approximate
equality (check how much num2 differs from 1.0, and if close enough,
accept the output), or b) solve the quadradic expression directly.
There's no need to loop here in first place.
So long,
Thomas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
elazro Guest
|
Posted: Mon Nov 21, 2005 10:31 am Post subject: Re: simple problem?? |
|
|
Your problem is that computers can't do exact floating point
arithmetic, since they have only finite precision. In particular, the
number 0.1 can not be represented exactly (it is probably stored as
approximately 0.10000000000000001). Thus, when you think num should be
1, it is actualy 1 plus a tiny fraction. Thus when num2 is calculated,
it is very close, but not quite, 1.0, and since it is not exactly
equal, the equality comparison fails.
This is a common problem when dealing with floating point computations
(in any language) - equality comparisons are next to useless (except
for a few special values such as 0, small integers, or dyadic
rationals). The solution is not to check for equality, but to check
that 2 numbers are close:
const double tolerance=1e-6;
....
if ( fabs(num2-1.0)
they are equal
More sophisticated methods may be needed when dealing with very large
numbers (i.e. looking at the ratio between two numbers). If you need to
know more about floating point computations, google for "What every
computer scientist should know about floating-point" for a paper on the
subject.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Mon Nov 21, 2005 10:32 am Post subject: Re: simple problem?? |
|
|
In article <1132440553.516288.321890 (AT) o13g2000cwo (DOT) googlegroups.com>,
<baygross (AT) gmail (DOT) com> wrote:
| Quote: | #include
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1) returns
true, but for some reason this code will never output: 1 and 0.5.
I am very new to c++, and would apreciate some suggestions?
-BG
Precisely because num is never 1 or 0.5 due to round off errors in |
0.1's representation in binary.
Don't compare floating point values directly with operator ==(), the
result requires an exact match and is not likely to occur as you noted
above.
simplest test is if(std::abs(num2-1.) < 1./16.)
f(x) = 3x - 2x^2 -1
f(0.4) = 1.2 - 1 - 2*.16 = -.12
f(0.6) = 0.8 - 2*,36 = .08
f(.9) = 1.7 - 2*,81 = .08
f(1.1) = 2.3 - 2*1.21 = 0.08
if(|f(x)| <1 /16 [=0.06125] ) is probably good enough for
this
if(std::num(num2-1) < 1./16,) is probably good enough replacement
for your if() line to obtain the result for this loop.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
usr.root@gmail.com Guest
|
Posted: Mon Nov 21, 2005 10:34 am Post subject: Re: simple problem?? |
|
|
[email]baygross (AT) gmail (DOT) com[/email] 写�:
| Quote: | #include
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1) returns
true, but for some reason this code will never output: 1 and 0.5.
I am very new to c++, and would apreciate some suggestions?
|
Don't use "==" between double and int,becasue they will never have the
same value.
if you should do that ,you can use num2-1<0.xxxx
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Suki Guest
|
Posted: Mon Nov 21, 2005 10:36 am Post subject: Re: simple problem?? |
|
|
The first thing you should keep in mind is never compare floating point
values for
equality. You can always compare them for < and > but not for ==.
To know why it is so, change the code to some thing like this.
Remove the if condition and re write the cout statement like this.
// It will print what you'd think 1 as something else. check it out.
cout << setprecision (17) << num << endl ;
or if you want to compare for equality then use this method.
#include
if (fabs (num2 - 1) < DBL_EPSILON)
cout << num << endl ;
Or a more fancier way
#include
if (fabs (num2 - 1) < numeric_limits
cout << num < endl ;
Surya
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Victor Bazarov Guest
|
Posted: Mon Nov 21, 2005 10:37 am Post subject: Re: simple problem?? |
|
|
[email]baygross (AT) gmail (DOT) com[/email] wrote:
| Quote: | #include
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1) returns
true, but for some reason this code will never output: 1 and 0.5.
I am very new to c++, and would apreciate some suggestions?
|
http://docs.sun.com/source/806-3568/ncg_goldberg.html
V
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ron House Guest
|
Posted: Mon Nov 21, 2005 10:38 am Post subject: Re: simple problem?? |
|
|
[email]baygross (AT) gmail (DOT) com[/email] wrote:
| Quote: | #include
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1) returns
true, but for some reason this code will never output: 1 and 0.5.
I am very new to c++, and would apreciate some suggestions?
|
This is not a C++ problem but a problem in floating point arithmetic.
Float and double are floating point types that represent numbers as a
binary fraction multiplied by a power of two. That is, whereas normal
scientific notation is:
point decimal-fraction * 10^some-power
floating point notation is:
point binary-fraction * 2^some-power
Unfortunately, in binary fractions it is impossible to exactly represent
the value 0.1 (decimal tenth), just as in decimal fractions it is
impossible to exactly represent one third - you get an infinitely
repeating number.
So when you add "0.1", you are actually adding a value that differs ever
so slightly from 0.1, due to the finite number of digits of
representation in any actual computer. Therefore your code never tests
the exact values 1 and 0.5.
If you replace 0.1 with any number that can be represented exactly as a
binary fraction (and has 0.5 and 1 as multiples) then you will see what
you expect. For example, try replacing 1 with 0.0625 (which is 1/16th,
i.e. an inverse power of two).
--
Ron House [email]house (AT) usq (DOT) edu.au[/email]
http://www.sci.usq.edu.au/staff/house
Ethics website: http://www.sci.usq.edu.au/staff/house/goodness
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Neelesh Bodas Guest
|
Posted: Mon Nov 21, 2005 12:40 pm Post subject: Re: simple problem?? |
|
|
[email]baygross (AT) gmail (DOT) com[/email] wrote:
| Quote: | int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
|
num2 has been used without initialization.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Mon Nov 21, 2005 12:41 pm Post subject: Re: simple problem?? |
|
|
In article <1132440553.516288.321890 (AT) o13g2000cwo (DOT) googlegroups.com>,
[email]baygross (AT) gmail (DOT) com[/email] writes
| Quote: | #include
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1) returns
true, but for some reason this code will never output: 1 and 0.5.
I am very new to c++, and would apreciate some suggestions?
|
Yes, study up why comparisons of floating point values produce
surprising results in many if not all computing languages.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Mon Nov 21, 2005 12:42 pm Post subject: Re: simple problem?? |
|
|
[email]baygross (AT) gmail (DOT) com[/email] wrote:
| Quote: | #include
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (num2==1)
cout << num << endl;
}
return(0);
}
***********************************************888
I know that when num=1 and also when num=0.5 then (num2==1)
returns true, but for some reason this code will never output:
1 and 0.5.
|
That's because num is never equal to 1.0, nor to 0.5.
| Quote: | I am very new to c++, and would apreciate some suggestions?
|
Nothing to do with C++, really. You're being deceived by
appearances. You aren't incrementing num by 0.1 each time
threw the loop, because 0.1 isn't representable as a floating
point variable (at least on any reasonably modern machine). So
you're adding something very, very close, and the errors add up.
See http://cch.loria.fr/documentation/IEEE754/ACM/goldberg.pdf.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Selvin Guest
|
Posted: Mon Nov 21, 2005 5:53 pm Post subject: Re: simple problem?? |
|
|
Witam,
| Quote: | Or a more fancier way
#include <limits
if (fabs (num2 - 1) < numeric_limits
cout << num < endl ;
|
i thought the same, but duno why its not working (MSVC++7.1)
#include
#include <limits>
#include <ostream>
using namespace std;
int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
{
num2=-2*(num*num)+3*(num);
if (std::abs (num2 - 1.0) <
numeric_limits
cout << num << endl;
}
return(0);
}
pozdrawiam
Przemek Sulikowski
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Selvin Guest
|
Posted: Mon Nov 21, 2005 5:54 pm Post subject: Re: simple problem?? |
|
|
Maybe im wrong but....
| Quote: | int main()
{
double num, num2;
for (num=-30; num<=30; num+=0.1)
....
num2 has been used without initialization.
|
in the same way num has been used without initialization, but it isnt
true...
| Quote: | {
num2=-2*(num*num)+3*(num);
num2 has been used without initialization.
|
no, this is initialization, num2 is l-value in this statment
pozdrawiam
Przemek Sulikowski
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|