why this funny double is not a true zero?
-
//print function
CString fmt(double db)
{
CString cs;
cs.Format("%f", db);
return cs;
}//problem
void TheDlg::Test00()
{
const double dbInf = 1.0/::sin(0); //infinite
const double dbZero = (::fabs(::cos(3.14159/2))<0.9)?0:1; //line 1CString cs; cs += fmt(dbZero)+"\\r\\n"; //line 2 cs += fmt(dbZero \* dbInf)+"\\r\\n"; //line 3 cs += fmt(0 \* dbInf)+"\\r\\n"; //line 4 MessageBox(cs);
}
above dbZero only has 2 possible values : 0 or 1 - see line 1; output:
0.000000
-1.#IND00
0.000000output of line 2 shows that dbZero is zero. output of line 3 shows that dbZero is not zero, since it is different from output of line 4. funny thing is that if change line 1 to:
const double dbZero = (0.1<0.9)?0:1;
Then all outputs are zeros. Why? How to make dbZero as a true zero in problem code?
-
//print function
CString fmt(double db)
{
CString cs;
cs.Format("%f", db);
return cs;
}//problem
void TheDlg::Test00()
{
const double dbInf = 1.0/::sin(0); //infinite
const double dbZero = (::fabs(::cos(3.14159/2))<0.9)?0:1; //line 1CString cs; cs += fmt(dbZero)+"\\r\\n"; //line 2 cs += fmt(dbZero \* dbInf)+"\\r\\n"; //line 3 cs += fmt(0 \* dbInf)+"\\r\\n"; //line 4 MessageBox(cs);
}
above dbZero only has 2 possible values : 0 or 1 - see line 1; output:
0.000000
-1.#IND00
0.000000output of line 2 shows that dbZero is zero. output of line 3 shows that dbZero is not zero, since it is different from output of line 4. funny thing is that if change line 1 to:
const double dbZero = (0.1<0.9)?0:1;
Then all outputs are zeros. Why? How to make dbZero as a true zero in problem code?
Floating point numbers are not exact. See: Comparing Floats[^]
The difficult we do right away... ...the impossible takes slightly longer.
-
//print function
CString fmt(double db)
{
CString cs;
cs.Format("%f", db);
return cs;
}//problem
void TheDlg::Test00()
{
const double dbInf = 1.0/::sin(0); //infinite
const double dbZero = (::fabs(::cos(3.14159/2))<0.9)?0:1; //line 1CString cs; cs += fmt(dbZero)+"\\r\\n"; //line 2 cs += fmt(dbZero \* dbInf)+"\\r\\n"; //line 3 cs += fmt(0 \* dbInf)+"\\r\\n"; //line 4 MessageBox(cs);
}
above dbZero only has 2 possible values : 0 or 1 - see line 1; output:
0.000000
-1.#IND00
0.000000output of line 2 shows that dbZero is zero. output of line 3 shows that dbZero is not zero, since it is different from output of line 4. funny thing is that if change line 1 to:
const double dbZero = (0.1<0.9)?0:1;
Then all outputs are zeros. Why? How to make dbZero as a true zero in problem code?
Just got a more consistent behaviour on Linux:
#include <cstdio>
#include <cmath>void out_double( double db )
{
printf("%f\n", db);
}int main()
{const double dbInf = 1.0/::sin(0); //infinite
const double dbZero = (::fabs(::cos(3.14159/2))<0.9)?0:1; //line 1out_double( dbZero );
out_double( dbZero * dbInf );
out_double( 0 * dbInf );}
outputs
0.000000
-nan
-nan[update] The same program, on Windows 8, compiled with Visual Studio 2012, produces
0.000000
-1.#IND00
-1.#IND00[/update]
-
Just got a more consistent behaviour on Linux:
#include <cstdio>
#include <cmath>void out_double( double db )
{
printf("%f\n", db);
}int main()
{const double dbInf = 1.0/::sin(0); //infinite
const double dbZero = (::fabs(::cos(3.14159/2))<0.9)?0:1; //line 1out_double( dbZero );
out_double( dbZero * dbInf );
out_double( 0 * dbInf );}
outputs
0.000000
-nan
-nan[update] The same program, on Windows 8, compiled with Visual Studio 2012, produces
0.000000
-1.#IND00
-1.#IND00[/update]
Hey there !! >>> LOOK OUT >>> LOOK OUT >>> LOOK OUT >>> LOOK OUT >>> The problem is NOT on the dbZero - but on the dbInf. That explains everything you see. dbInf is 1 divided by zero, which is undefined. Anytime you try to use this value, you´ll have problems. That´s why you CAN print dbZero, but not dbInf or (dbZero * dbInf). Ok ?
-
//print function
CString fmt(double db)
{
CString cs;
cs.Format("%f", db);
return cs;
}//problem
void TheDlg::Test00()
{
const double dbInf = 1.0/::sin(0); //infinite
const double dbZero = (::fabs(::cos(3.14159/2))<0.9)?0:1; //line 1CString cs; cs += fmt(dbZero)+"\\r\\n"; //line 2 cs += fmt(dbZero \* dbInf)+"\\r\\n"; //line 3 cs += fmt(0 \* dbInf)+"\\r\\n"; //line 4 MessageBox(cs);
}
above dbZero only has 2 possible values : 0 or 1 - see line 1; output:
0.000000
-1.#IND00
0.000000output of line 2 shows that dbZero is zero. output of line 3 shows that dbZero is not zero, since it is different from output of line 4. funny thing is that if change line 1 to:
const double dbZero = (0.1<0.9)?0:1;
Then all outputs are zeros. Why? How to make dbZero as a true zero in problem code?
Hey there !! LOOK OUT - LOOK OUT - LOOK OUT - LOOK OUT - :~ The problem is NOT on the dbZero - but on the dbInf. :confused: That explains everything you see. dbInf is 1 divided by zero, which is undefined. Anytime you try to use this value, you´ll have problems. That´s why you CAN print dbZero, but not dbInf or (dbZero * dbInf). Ok ?