Velocity Reviews > C++ > Comparing two doubles

# Comparing two doubles

nicolas
Guest
Posts: n/a

 09-20-2003
I was very surprised by the output of the following program:

#include <iostream>
#include <numeric>

int main() {

double vals_1[5]= { 0.5, 0.2, 0.1, 0.1, 0.1 };
double vals_2[5]= { 0.1, 0.1, 0.1, 0.2, 0.5 };
double sum1 = std::accumulate( vals_1, vals_1+5, 0. );
double sum2 = std::accumulate( vals_2, vals_2+5, 0. );
if( sum1 != 1. )
std::cout << "sum1 not ok ";
else
std::cout << "sum1 ok ";
if( sum2 != 1. )
std::cout << "sum2 not ok";
else
std::cout << "sum2 ok";

std::cout << std::endl;
}

the output is: sum1 not ok sum2 ok

Is that behavior to be expected? Do I have to use a function that
compares up to some precision everytime
I want to compare 2 doubles? I tried changing double to float: in that
case both sums are ok.

Artie Gold
Guest
Posts: n/a

 09-20-2003
nicolas wrote:
> I was very surprised by the output of the following program:
>
> #include <iostream>
> #include <numeric>
>
> int main() {
>
> double vals_1[5]= { 0.5, 0.2, 0.1, 0.1, 0.1 };
> double vals_2[5]= { 0.1, 0.1, 0.1, 0.2, 0.5 };
> double sum1 = std::accumulate( vals_1, vals_1+5, 0. );
> double sum2 = std::accumulate( vals_2, vals_2+5, 0. );
> if( sum1 != 1. )
> std::cout << "sum1 not ok ";
> else
> std::cout << "sum1 ok ";
> if( sum2 != 1. )
> std::cout << "sum2 not ok";
> else
> std::cout << "sum2 ok";
>
> std::cout << std::endl;
> }
>
>
> the output is: sum1 not ok sum2 ok
>
> Is that behavior to be expected? Do I have to use a function that
> compares up to some precision everytime
> I want to compare 2 doubles? I tried changing double to float: in that
> case both sums are ok.
>

See:

http://www.eskimo.com/~scs/C-faq/q14.5.html

(It's from the C-FAQ, but is the same for C++.)

HTH,
--ag

--
Artie Gold -- Austin, Texas

JustSomeGuy
Guest
Posts: n/a

 09-20-2003
I think the prolem lies with the fact that .1 and .2 cannot be expressed in
binary...

"nicolas" <(E-Mail Removed)> wrote in message
news:bkgclo\$pma\$(E-Mail Removed)...
> I was very surprised by the output of the following program:
>
> #include <iostream>
> #include <numeric>
>
> int main() {
>
> double vals_1[5]= { 0.5, 0.2, 0.1, 0.1, 0.1 };
> double vals_2[5]= { 0.1, 0.1, 0.1, 0.2, 0.5 };
> double sum1 = std::accumulate( vals_1, vals_1+5, 0. );
> double sum2 = std::accumulate( vals_2, vals_2+5, 0. );
> if( sum1 != 1. )
> std::cout << "sum1 not ok ";
> else
> std::cout << "sum1 ok ";
> if( sum2 != 1. )
> std::cout << "sum2 not ok";
> else
> std::cout << "sum2 ok";
>
> std::cout << std::endl;
> }
>
>
> the output is: sum1 not ok sum2 ok
>
> Is that behavior to be expected? Do I have to use a function that
> compares up to some precision everytime
> I want to compare 2 doubles? I tried changing double to float: in that
> case both sums are ok.
>

Jacek Dziedzic
Guest
Posts: n/a

 09-21-2003
Floating point addition is not commutative, hence your
result. Never count on comparing floating point values
directly (via "=="), instead try comparing their difference
with a threshold value, via "<" and/or ">".

HTH,
- J.